gym102341 C. Cloyster(交互,思维,二分)
Posted live4m
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gym102341 C. Cloyster(交互,思维,二分)相关的知识,希望对你有一定的参考价值。
题意:
解法:
先取中间的一行,找到最大值,
然后找最大值上下的6个方向的值,如果找不到更大的值,那么当前最大值就是答案.
如果找到了更大的值,如果更大的值在上面,那么最大值一定也在上面.
因为数互不相同,每个数沿着更大数一直走一定能走倒最大值,
由于已经从中间用比较小的数隔开了,更大值不可能走过中间隔开的线,
因此最大值一定在上方.
第二次则对上半部分取中间的竖线,找到更大值在左边还是右边,
一直重复直到找到最大值.
询问次数大概是O(n+n/2+n/4+....)=O(2n)
code:
#include<bits/stdc++.h>
using namespace std;
const int maxm=2e3+5;
int dx[]={0,0,1,-1,1,1,-1,-1};
int dy[]={1,-1,0,0,-1,1,-1,1};
int a[maxm][maxm];
int ma,mx,my;
int n;
int ask(int i,int j){
if(a[i][j])return a[i][j];
cout<<"? "<<i<<' '<<j<<endl;
cin>>a[i][j];return a[i][j];
}
void out(int x,int y){
cout<<"! "<<x<<' '<<y<<endl;
}
void get(int i,int j){
int t=ask(i,j);
if(t>ma){
ma=t;mx=i,my=j;
}
}
void getAll(int i,int j){
for(int k=0;k<8;k++){
int x=i+dx[k];
int y=j+dy[k];
if(x<1||x>n||y<1||y>n)continue;
get(x,y);
}
}
void solve(){
cin>>n;
int l1=1,r1=n;
int l2=1,r2=n;
while(1){
if(r1-l1>=r2-l2){//查询中间行
int mid=(l1+r1)/2;
for(int j=l2;j<=r2;j++){//枚举列
get(mid,j);
}
getAll(mx,my);
if(mx==mid){
out(mx,my);return ;
}
if(mx<mid){
r1=mid-1;
}else{
l1=mid+1;
}
}else{//查询中间列
int mid=(l2+r2)/2;
for(int i=l1;i<=r1;i++){//枚举行
get(i,mid);
}
getAll(mx,my);
if(my==mid){
out(mx,my);return ;
}
if(my<mid){
r2=mid-1;
}else{
l2=mid+1;
}
}
}
out(mx,my);
}
signed main(){
solve();
return 0;
}
以上是关于gym102341 C. Cloyster(交互,思维,二分)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces gym102222 C. Caesar Cipher 签到
Codeforces Gym 101142 C. CodeCoder vs TopForces(思维+图论)