【EOJ Monthly 2019.02 - A】回收卫星(交互题型,二分)
題干:
單測試點時限: 1.0 秒
內存限制: 256 MB
“這個世上沒有無用的齒輪,也只有齒輪本身能決定自己的用途。”
就像太空中的衛星,雖然不計其數,但都各司其職。
但沒有一個東西是能夠永遠無損的。為了便于回收及修理,衛星在故障后會生成一個球形的星場,與之配對的感應器能判斷其是否在星場內。
QQ 小方現在要負責衛星的回收工作,他負責使用這些感應器鎖定衛星的位置。QQ 小方有衛星基本的運動信息,因此每次工作時,他都能保證自己與衛星保持相對靜止,以及自己在星場內。因此,可以將 QQ 小方看作空間直角坐標系的原點 (0,0,0) ,而星場是一個中心坐標為 (x,y,z) (?109≤x,y,z≤109 ) ,半徑為 r (1≤r≤109 ) 且包含原點的球,其中 x,y,z,r 都是整數。但接下來,QQ 小方需要你的幫助。
為了回收衛星,QQ 小方每次能向一個整點發射一個感應器,感應器會返回它是否在星場里。由于經費緊張,QQ 小方只能發射不超過 200 個感應器,你能幫助他找到衛星的具體坐標 (x,y,z) 嗎?
星場邊界上的點視為在星場內部。
交互流程
每一行輸出四個整數 0,xi,yi,zi ,代表向 (xi,yi,zi ) 發射一個感應器。隨后,交互程序會輸出 1 / 0 ,代表感應器在 / 不在星場內。
收集足夠多的數據之后,輸出四個整數 1,x,y,z ,代表確定衛星的坐標是 (x,y,z) 。之后,你的程序不應再有任何輸出。
樣例
Input
0 0 0 0 0 0Output
0 2 0 0 0 -2 0 0 0 0 2 0 0 0 -2 0 0 0 0 2 0 0 0 -2 1 0 0 0提示
對于樣例:
球場的中心是 (0,0,0 ),半徑為 1 。
在交互過程中,依次訪問了 (2,0,0 ), (?2,0,0 ), (0,2,0 ), (0,?2,0 ), (0,0,2 ), (0,0,?2 ) 六個點,但這六個點都不在球場內。因為原點在球場內,所以球場中心一定位于 (0,0,0 ),半徑為1 。(當然,也有可能是運氣好,但這個球的中心的確是(0,0,0 ) 。)
解題報告:
? ?因為題目中說了原點一定是其中的點,所以我們直接分成三個坐標軸上(也就是求x的時候其他兩個坐標都是0),分別二分求中點,最后結果一定就是答案了。
以 x 軸為例,因為原點在球內,球面和 x 軸的正負半軸(含原點)一定各有一個交點。如果兩個交點分別為 (x1,0,0 ) 和 (x2,0,0 ),則球心一定在這兩點所成線段的垂直平分面上。因為線段在 x 軸上,所以所得到平面的表達式是 x=x1+x22 ,相當于確定了球心在 x 軸上的坐標。
因此,只要求出兩個交點的中點坐標即可。交點坐標可能含有小數,但是依舊可以通過二分法求出半軸上第一個不在球內,或最后一個在球內的點的坐標。對正負半軸各求一次,根據對稱性,所得兩點的中點坐標應該與真實交點中點坐標相同,因此可以在約 2×30=60 次操作內確定球心在 x 軸上的坐標。(因為題干中說了最終答案為整數)
同樣地,可以用此方法求出球心在 y 軸,z 軸上的坐標,得解。
有一個常見錯誤是:二分交點從 109 開始。雖然 x,y,z,r≤109 ,但交點坐標絕對值可以大于 109 , 值 ≤2×109 。同時,此時的 l+r2 會在 l+r 時爆 int。
還有就是注意交互題型,如果要scanf讀入的話一定不要忘了printf后面加fflush(stdout)。。
AC代碼:
#include<bits/stdc++.h> #define ll long long using namespace std; const ll INF=2e9; ll a[5]; void ask(int tp,int m) {for(int i=1; i<=3; i++)a[i]=0;a[tp]=m;printf("0 %lld %lld %lld\n",a[1],a[2],a[3]);fflush(stdout); } ll go(int tp) {ll l=0,r=INF,mid,ans1=0,ans2=0;int op;while(l<=r) {mid=l+(r-l)/2;ask(tp,mid);scanf("%d",&op);if(op)l=mid + 1,ans1 = mid;else r=mid - 1;}l=-INF,r=0;while(l<=r) {mid=l+(r-l)/2;ask(tp,mid);scanf("%d",&op);if(op)r=mid-1,ans2 = mid;else l=mid+1;}return (ans1+ans2)/2; } int main() {ll x,y,z;x=go(1);y=go(2);z=go(3);printf("1 %lld %lld %lld\n",x,y,z);return 0 ; }?
總結
以上是生活随笔為你收集整理的【EOJ Monthly 2019.02 - A】回收卫星(交互题型,二分)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 信用卡申请以卡办卡 获批高额度不是问题
- 下一篇: 哪怕不去上班,在银行存款有了这个数,每月