题解:P8135 [ICPC 2020 WF] QC QC
zh1221_qwq · · 题解
和其他题解不一样,不知道为什么能过的做法。
先考虑假设我们知道一个不故障的机器怎么做,那我们第一轮可以随机询问一个值,这样就能知道他是否故障,假设他不故障下一轮就可以询问两个值,以此类推。
然后我们每一次也可以对其他的做随机询问,这样有可能对后面的递推有帮助。具体的,我们将所有机器分为
显然第二种是没啥用的,问出来不能有任何帮助,不考虑他们。第一类记为
我们从
然后更新一遍当前新确定的值,注意当前新确定的因为前面几次也对他做了询问,所以他也可以确定出来新的新确定的。
这样实现就是大约
然后考虑怎么询问出一个不故障的机器,考虑给的性质不故障的比故障的多,那我们将所有值两两配对,如果他们互相返回的值中有
这样一直撇一直撇最后一定全剩下不故障的,次数大概是,你考虑现在有
这样大概还有几次的空间,我们考虑如果
然后你再去跑刚才的那个做法,因为你前面的询问记忆化了很多,所以实际上跑起来还是差不多
::::info[代码]
#include<bits/stdc++.h>
using namespace std;
#define bui __builtin_popcountll
#define pii pair<int,int>
#define se second
#define fi first
#define mid ((l+r)>>1)
#define qwq cout<<"----------------------------------------------------------------------";
const int inf=1e18;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void prt(int x){
if(x<0)putchar('-'),x=-x;
if(x<10)putchar(x+'0');
else prt(x/10),putchar(x%10+'0');
}
int ksm(int x,int y,int mod){
int ans=1;
while(y){
if(y&1ll)ans=ans*x%mod;
y>>=1;
x=x*x%mod;
}
return ans;
}
const int N=1e2+5;
int gcd(int x,int y){return (y)?gcd(y,x%y):x;}
int max(int x,int y){return (x>y)?x:y;}
int min(int x,int y){return (x<y)?x:y;}
int a[N][N];
int n;
int p[N];
bool vis[N];
char lss[N];
int val[N];
vector<int>query(vector<int>q){
cout<<"test ";
for(int i=0;i<q.size();i++)cout<<q[i]+1<<" ";
cout<<endl;
scanf("%s",lss+1);
vector<int>tot;
for(int i=1;i<=n;i++){
if(lss[i]=='-')tot.push_back(-1);
else if(lss[i]=='0')tot.push_back(0);
else tot.push_back(1);
}
return tot;
}
int tot;
void sl(){
n=read();
srand(time(0)*114);
int x=0;
memset(a,-1,sizeof(a));
vector<int>q,b,lp,rp,lx,rx;
q.resize(n);
int ww=0;
for(int i=0;i<n;i++)p[i+1]=i;
tot=n;
int tm=0;
while(tot>2){
// for(int i=1;i<=tot;i++){
// cout<<p[i]<<" ";
// }
// cout<<"\n";
bool flag=1;
for(int i=1;i<=tot;i++){
for(int j=1;j<=tot;j++){
if(i!=j){
if(a[p[i]][p[j]]!=1)flag=0;
}
}
}
if(flag)break;
random_shuffle(p+1,p+tot+1);
memset(vis,0,sizeof(vis));
for(int i=1;i<=tot;i++)vis[p[i]]=1;
lp.clear();rp.clear();lx.clear(),rx.clear();
for(int i=0;i<n;i++){
if(!vis[i])lx.push_back(i),rx.push_back(i);
}
if(tm==4){
random_shuffle(lx.begin(),lx.end());
for(int i=0;i<lx.size();i++){
q[rx[i]]=lx[i];
}
for(int i=1;i<=tot;i++){
q[p[i]]=p[i+1];
if(i==tot)q[p[i]]=p[1];
}
b=query(q);
for(int i=0;i<n;i++){
if(q[i]!=-1)a[i][q[i]]=b[i];
}
flag=1;
for(int i=1;i<=tot;i++){
if(b[p[i]]!=1)flag=0;
}
if(flag)break;
tm++;
continue;
}
for(int i=2;i<=tot;i+=2){
if(a[p[i]][p[i-1]]==-1)q[p[i]]=p[i-1];
else lp.push_back(p[i-1]),rp.push_back(p[i]);
if(a[p[i-1]][p[i]]==-1)q[p[i-1]]=p[i];
else lp.push_back(p[i]),rp.push_back(p[i-1]);
}
if(n%2)lp.push_back(p[tot]),rp.push_back(p[tot]);
random_shuffle(lp.begin(),lp.end());
random_shuffle(lx.begin(),lx.end());
for(int i=0;i<lp.size();i++){
q[rp[i]]=lp[i];
}
for(int i=0;i<lx.size();i++){
q[rx[i]]=lx[i];
}
b=query(q);
// for(int i=0;i<n;i++){
// cout<<b[i]<<" ";
// }
// cout<<"\n";
for(int i=0;i<n;i++){
if(q[i]!=-1)a[i][q[i]]=b[i];
}
int ls=0;
for(int i=2;i<=tot;i+=2){
if(a[p[i]][p[i-1]]==1&&a[p[i-1]][p[i]]==1){
p[++ls]=p[i-1];
p[++ls]=p[i];
}
}
if(n%2)p[++ls]=p[tot];
if(tot==ls)tm++;
else tm=0;
tot=ls;
}
x=p[1];
for(int i=0;i<n;i++)p[i+1]=i;
memset(val,-1,sizeof(val));
int cnt=1;
val[x]=1;
for(int k=0;k<n;k++){
bool flag=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(val[i]==1&&a[i][j]!=-1&&val[j]==-1){
val[j]=a[i][j];
flag=1;
cnt++;
}
}
}
if(!flag)break;
}
while(cnt!=n){
vector<int>su,ed;
for(int i=0;i<n;i++){
if(val[i]==1)su.push_back(i);
if(val[i]==-1)ed.push_back(i);
q[i]=-1;
}
random_shuffle(su.begin(),su.end());
random_shuffle(ed.begin(),ed.end());
for(int i=0;i<min(su.size(),ed.size());i++){
q[su[i]]=ed[i];
}
if(su.size()<ed.size()){
lp.clear(),rp.clear();
for(int i=su.size();i<ed.size();i++){
lp.push_back(ed[i]);
}
for(int i=0;i<ed.size();i++)rp.push_back(ed[i]);
random_shuffle(lp.begin(),lp.end());
random_shuffle(rp.begin(),rp.end());
for(int i=0;i<lp.size();i++){
q[rp[i]]=lp[i];
}
if(lp.size()!=1){
for(int i=0;i<lp.size();i++){
if(q[rp[i]]==rp[i]){
if(i)swap(q[rp[i]],q[rp[i-1]]);
else swap(q[rp[i]],q[rp[i+1]]);
}
}
}
}
b=query(q);
for(int i=0;i<n;i++){
if(q[i]!=-1){
a[i][q[i]]=b[i];
}
}
for(int k=0;k<n;k++){
bool flag=0;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(val[i]==1&&a[i][j]!=-1&&val[j]==-1){
val[j]=a[i][j];
flag=1;
cnt++;
}
}
}
if(!flag)break;
}
}
cout<<"answer ";
for(int i=0;i<n;i++)cout<<val[i];
cout<<endl;
}
signed main(){
int t=1;
t=read();
while(t--)sl();
return 0;
}
/*
你的变量是否是局部变量?递归之后改掉就不是一个值了?(可持久化)
*/
::::