加载中...

二分

二分

关键点 :

1.if条件对应答案某一段 (mid<=x) 当是最左侧的时候也符合,这个时候你就让他l=mid 才能找到x
2.mid每次为在左边界 所以找满足条件往右走的数 5 5
3.四种写法,只有两种写法是对。如果是边界不存在的事物,会因为if失败趋于同一个边。中间不存在或者都能考他找到。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e6+10;
int n,m;
int a[N];
void find(int x){
    cout<<"l"<<" "<<"r"<<" "<<"a[l]"<<" "<<"a[r]"<<endl;
    //if(mid与原数组)条件对应答案某一段 r为边界说明找到最左边 l为边界说明找到最右边
    int l=0,r=n-1;
    while(l<r){//mid在最右边 找最左边满足条件的数 1 1
        int mid=l+r>>1;
        if(a[mid]>=x ) r=mid;// >=x的这一段 进入语句  每次设置右边界 会找到>=x的第一个数
        else l=mid+1;
        cout<<l;
    }
    cout <<l<<" "<< r<<" "<<a[l]<<" "<<a[r]<<endl;
    
    l=0,r=n-1;
    while(l<r){//mid在最左边 找最右边满足条件的数  超时 2 2
        int mid=l+r+1>>1;
        if(a[mid]<=x) l=mid;//<=x这一段 进入语句 让mid为左边界 会找到 <=x 的最右边的数
        else r=mid-1;
        cout<<l;
    }
    cout <<l<<" "<< r<<" "<<a[l]<<" "<<a[r]<<endl;
    
    //
    l=0,r=n-1;
    while(l<r){//mid每次为右边界 所以找满足条件往左走的数  0 0
        int mid=l+r>>1;
        if(a[mid]<=x) r=mid;//r=mid 直接让右边界=mid 会找到<=x的第一个数
        else l=mid+1;
        cout<<l;
    }
    cout <<l<<" "<< r<<" "<<a[l]<<" "<<a[r]<<endl;
    
    l=0,r=n-1;
    while(l<r){//mid每次为在左边界 所以找满足条件往右走的数  5 5
        int mid=l+r+1>>1;
        if(a[mid]>=x) l=mid;//会找到>=x 的最右边
        else r=mid-1;
        cout<<l;
    }

    cout <<l<<" "<< r<<" "<<a[l]<<" "<<a[r]<<endl;
    cout<<endl;
    
}
int main()
{   
    cin>>n>>m;
    for (int i = 0; i < n; i ++ ) scanf("%d",&a[i]);
    for (int i = 0; i < m; i ++ ){
        int x;cin>>x;
        
        find(x);
    }
    
    return 0;
}

https://atcoder.jp/contests/abc269/tasks/abc269_e
你可以询问 x属于(a,b) y属于(c,d) 的(x,y)的方格里有多少个放了把数码的皇后
解: 直接二分 x属于1-mid y属于1-n 问问是不是满足1-mid每一行都有格子是的话就得往mid+1 -r找

int n,x,y;
inline bool checky(int a,int b,int c,int d){
    cout<<"? "<<a<<' '<<b<<' '<<c<<' '<<d<<endl;
    int num;cin>>num;
    if((d-c+1)==num) return false;
    else return true;
}
inline bool checkx(int a,int b,int c,int d){
    cout<<"? "<<a<<' '<<b<<' '<<c<<' '<<d<<endl;
    int num;cin>>num;
    if((b-a+1)==num) return false;
    else return true;
}
inline void bsx(){
    int l=1,r=n;
    while (l < r){
        int mid = l + r >> 1;
        if (checkx(1,mid,1,n)) r = mid;
        else l = mid + 1;
    }
    x=l;
}
inline void bsy(){
    int l=1,r=n;
    while (l < r){
        int mid = l + r >> 1;
        if (checky(1,n,1,mid)) r = mid;
        else l = mid + 1;
    }
    y=l;
}
int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);std::cout.tie(0);
    cin>>n;
    bsx();bsy();
    cout<<'!'<<' '<<x<<' '<<y<<endl;
}

posted @ 2022-09-19 17:26  liang302  阅读(63)  评论(0编辑  收藏  举报