题目链接 琪亚娜世界第一可爱
现在有6个数{4 8 15 16 23 42}组成的序列,但是我们不知道这个序列的具体顺序。我们可以询问最多4次,每次询问有两个参数 i,j,返回 ai⋅aj。
首先我们要通过4次询问确定5个数的位置,那么最后一个数也就确定了。
所以我们每次询问{1 2} {1 3} {1 4} {1 5},然后求这4个数的gcd。
但是注意!
当GCD(a2,a3,a4,a5) != 1 的时候,gcd != a1,而GCD在这个题中,不为1则为2,而且GCD==2时,gcd为 30 或者 46,特判一下就可以。
#pragma GCC diagnostic error "-std=c++11"
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define Pair pair<int,int>
#define re return
#define getLen(name,index) name[index].size()
#define mem(a,b) memset(a,b,sizeof(a))
#define Make(a,b) make_pair(a,b)
#define Push(num) push_back(num)
#define rep(index,star,finish) for(register int index=star;index<finish;index++)
#define drep(index,finish,star) for(register int index=finish;index>=star;index--)
using namespace std;
int gcd(int a,int b)
{
if(a<b)
return gcd(b,a);
if(b==0)
return a;
if(a%2)
{
if(b%2)
return gcd(b,a-b);
else
return gcd(a,b>>1);
}
else
{
if(b%2)
return gcd(a>>1,b);
else
return 2*gcd(a>>1,b>>1);
}
}
int num[6]={4, 8, 15, 16, 23, 42};
int q[5];
vector<int> store;
set<int> unappear;
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
rep(i,0,6)
unappear.insert(num[i]);
rep(i,1,5){
cout<<"? 1 "<<i+1<<endl;
cin>>q[i];
}
int a=q[1];
rep(i,2,5){
a=gcd(a,q[i]);
}
if(a==30 || a==46)
a/=2;
store.Push(a);
unappear.erase(a);
rep(i,1,5){
store.Push(q[i]/a);
unappear.erase(q[i]/a);
}
rep(i,0,6){
if(unappear.find(num[i])!=unappear.end()){
store.Push(num[i]);
break;
}
}
cout<<"! ";
for(auto ele : store)
cout<<ele<<" ";
cout<<endl;
re 0;
}