D1. Too Many Impostors (easy version)(思维)

Problem - D1 - Codeforces

这是一个互动的问题。简单版和困难版的唯一区别是题数的限制。有n个玩家,从1到n,可以保证n是3的倍数。其中,有k个冒名顶替者和n-k个船员。冒名顶替者的数量,k,不是已知的。可以保证k <在每个问题中,你可以选择三个不同的整数a, b, c (1s a, b, c S n),然后问:“在标记为a, b和c的玩家中,冒名顶替者更多还是组员更多?”如果冒名顶替者比船员多,你将得到整数O,否则是1。在问最多2n个问题后,找出冒名顶替者的数量k和冒名顶替者的指数。评审团是自适应的,这意味着冒名顶替者的指标可能不是事先确定的,可以取决于你的问题。可以保证在任何时候至少有一组冒名顶替者满足约束条件和您的问题的答案。输入每个测试包含多个测试用例。第一行包含测试用例的数量t (1 S t 100)。测试用例的描述如下。每个测试用例的第一行也是唯一一行包含一个整数n (6 < n < 104, n是3的倍数)——玩家的数量。它保证所有测试用例的n的和不超过2- 104。

Example

input

Copy

2
6

0

1

9

1

output

Copy

? 1 2 3

? 3 4 5

! 3 4 1 2

? 7 1 9

! 4 2 3 6 8

题解:
像题中所给的

? 1 2 3

? 3 4 5

只一个共同数,是得不到什么有用的信息的

所以我们这样询问

假设a,b,c,d

? a b c

? b c d

如果询问结果相同则不用考虑,

否则我们可以知道

假设? a b c 为1

?b c d为0

b c肯定有一个0 和一个 1,否则询问不会不同

那么我们就可以确定a为1 d为0

确定了两个数,剩下的n - 2个数,每次直接与这两个数进行询问即可,若为0,肯定是我们需要的

总共询问数为n + n - 2, 

#include<iostream>
#include<string>
#include<vector>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
int res[100050];
void solve() 
{
	int n;
	cin >> n;
	vector<int> ans;
	for(int i = 0;i < n;i++)
	{
		cout <<"? "<<i + 1<<" "<<(i +1)%n + 1<<" "<<(i+2)%n + 1<<"\n";
		cin >> res[i];
	}
	for(int i = 0;i < n;i++)
	{
		if(res[i] != res[(i + 1)%n])
		{
			if(res[i] == 0)
			{
				ans.push_back({i + 1});
			}
			else
			{
				ans.push_back({(i + 3)%n + 1});
			}
			for(int j = 0;j < n;j++)
			{
				if(j != i&&j != (i + 3)%n)
				{
					cout <<"? "<<i + 1<<" "<<(i + 3)%n + 1<<" "<<j + 1<<"\n";
				    int p;
				    cin >> p;
				    if(p == 0)
			     	{
				   	    ans.push_back(j + 1);
			     	}
				}
			}
			break;
		}
	}
	cout << "! "<<ans.size();
	for(auto x:ans)
	{
		cout << " "<<x;
//		printf(" %d",x);
	} 
	cout <<"\n";
}
 
//1 2 4
signed main() 
{
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
	int t = 1;
	cin >> t;
//    scanf("%d",&t);
	while (t--) 
	{
		solve();
	}
	return 0;
}
//1 1 1 0 1
 
//1 1 1 0 1
//1 1 1 0 1
//1 1 1 0 1
//0 1 1 1 1
//0 1 1 1 1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值