二分找6点定球心 交互题

https://acm.ecnu.edu.cn/contest/140/problem/A/

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
0

Output

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 ) 。)

人生第一道交互题,一直读不懂题目。六个点定一个 圆心!输出用cout不要用printf,否则会Idleness limit exceeded eoj。 另外二分不能是0到1e9而应该是0到1e9*2,注意二分的技巧。(不是输出l而是记录mid)

#include <iostream>
#include <cstdio>
using namespace std;
#define ll long long int 
#define res register int 
#define inf 0x3f3f3f3f
ll x,y,z,x1,x2,y1,y2,z1,z2,l,r,temp;
int op;
int main()
{
	l=0,r=2*1e9;
	while(l<=r){
		int mid=(l+r)>>1;
		cout<<0<<" "<<mid<<" "<<0<<" "<<0<<endl;
		scanf("%d",&op);
		if(op){
			l=mid+1;
			temp=mid;
		}else r=mid-1;
	}
	x1=temp;
	l=-2*1e9,r=0;
	while(l<=r){
		int mid=(l+r)>>1;
		cout<<0<<" "<<mid<<" "<<0<<" "<<0<<endl;
		scanf("%d",&op);
		if(op){
			r=mid-1;
			temp=mid;
		}else l=mid+1;
	}
	x2=temp; 
	x=(x1+x2)>>1;
	
	
	l=0,r=2*1e9;
	while(l<=r){
		int mid=(l+r)>>1;
		cout<<0<<" "<<0<<" "<<mid<<" "<<0<<endl;
		scanf("%d",&op);
		if(op){
			l=mid+1;
			temp=mid;
		}else r=mid-1;
	}
	y1=temp;
	l=-2*1e9,r=0;
	while(l<=r){
		int mid=(l+r)>>1;
		cout<<0<<" "<<0<<" "<<mid<<" "<<0<<endl;
		scanf("%d",&op);
		if(op){
			r=mid-1;
			temp=mid;
		}else l=mid+1;
	}
	y2=temp;
	y=(y1+y2)>>1;
	
	
	l=0,r=2*1e9;
	while(l<=r){
		int mid=(l+r)>>1;
		cout<<0<<" "<<0<<" "<<0<<" "<<mid<<endl;
		scanf("%d",&op);
		if(op){
			l=mid+1;
			temp=mid;
		}else r=mid-1;
	}
	z1=temp;
	l=-2*1e9,r=0;
	while(l<=r){
		int mid=(l+r)>>1;
		cout<<0<<" "<<0<<" "<<0<<" "<<mid<<endl;
		scanf("%d",&op);
		if(op){
			r=mid-1;
			temp=mid;
		}else l=mid+1;
	}
	z2=temp;
	z=(z1+z2)>>1;	

	cout<<1<<" "<<x<<" "<<y<<" "<<z;
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值