2020-2021 ICPC Northwestern European Regional Programming Contest (NWERC 2020) D. Dragon Balls (思维,

2020-2021 ICPC Northwestern European Regional Programming Contest (NWERC 2020)  D. Dragon Balls (思维,

  • 题意:有\(n\)个龙珠在坐标轴上,你每次可以询问一个坐标,返回给你距离你坐标最近的龙珠的距离的平方,当这个距离等于\(0\)时,说明找到一颗龙珠.

  • 题解:这题主要有两个点:

    1.首先询问\((0,0)\),可以确定一颗龙珠的距离

    2.对于这个距离,我们枚举\(x\)的可能坐标,然后因为距离固定,可以得到\(y\)的坐标,判断\(y\)坐标是不是完全平方数,可以证明:\(x\)和\(y\)同为完全平方数的数的个数很少,然后我们去枚举这些数即可,一定有一个坐标是我们要找的龙珠.

  • 代码:

    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
     
    ll check(int k,ll l,ll r,ll x){
        if(l==r) return l;
        ll mid=(l+r)>>1;
        ll tmp=1;
        rep(i,1,k) tmp*=mid;
        if(tmp<x) return check(k,mid+1,r,x);
        else return check(k,l,mid,x);
    }
     
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    	int n;
    	cin>>n;
    	vector<PLL> pt;
    	rep(i,1,n){
    		cout<<0<<' '<<0<<'\n';
    		cout.flush();
    		ll dis;
    		cin>>dis;
    		if(dis==0){
    			continue;
    		}
    		pt.clear();
    		for(ll i=0;i*i<=dis;++i){
    			ll x=i*i;
    			ll y=dis-x;
    			if(y<0) continue;
    			ll tmp=check(2,0,1500000000,y);
    			if(tmp*tmp==y){
    				pt.pb({i,tmp});
    			}
    		}
    		for(auto w:pt){
    			ll x=w.fi;
    			ll y=w.se;
    			if(x<0 || x>1000000 || y<0 || y>1000000) continue;
    			cout<<x<<' '<<y<<'\n';
    			cout.flush();
    			ll now;
    			cin>>now;
    			if(now==0){
    				break;
    			}
    		}
    	}
     
        return 0;
    }
    
上一篇:P5025 [SNOI2017]炸弹


下一篇:Link with Balls 题解(结论题+组合数学)