简要题意:
这是一道交互题。
有一个大小为
希望找到一个出度不小于
首先出度不小于
考虑对于一个已经确定内部形态的,可能的集合
- 枚举一个
,将 加入 中; - 求出
内的所有边并删除不可能的点。
因为若确定内部形态的点并且全都可能的集合大小为
故最后可能的集合为
第一步最多是
注意到实际上对于大部分情况下第一步删除一个点的步数是小于
经过本机的测试,可以通过。
下面其实是求助,因为我并不会证明平均次数在
附我的代码:
// Author: cnyz
#include "city.h"
#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define pb emplace_back
using namespace std;
const int N=1005;
mt19937 rng(time(0));
vector<int> pos[N];
int deg[N],p[N];
int vis[N][N];
set<int> now;
int nn;
bool Ask(int x,int y) {
bool F=vis[x][y]!=-1?vis[x][y]:ask(x,y);
vis[x][y]=F,vis[y][x]=F^1;
return F;
}
void qry(int x,int y) {
bool fl=Ask(x,y);
if(fl) deg[y]++,pos[x].pb(y);
else deg[x]++,pos[y].pb(x);
}
bool chk(int u) {
int tmp=0;
shuffle(p+1,p+nn+1,rng);
FOR(i,1,nn) if(u!=p[i]) {
tmp+=Ask(p[i],u);
if(tmp>=2) return 0;
}
return 1;
}
int solve(int n) {
nn=n;
FOR(i,1,n) deg[i]=0,pos[i].clear(),p[i]=i;
FOR(i,1,n) FOR(j,1,n) vis[i][j]=-1;
shuffle(p+1,p+n+1,rng);
now.clear(),now.insert(p[1]);
FOR(i,2,n) {
for(int j:now) qry(p[i],j);
now.insert(p[i]);
vector<int> tmp;tmp.clear();
for(int j:now) if(deg[j]>=2) tmp.pb(j);
for(int j:tmp) now.erase(j);
}
vector<int> tmp;tmp.clear();
for(int u:now) tmp.pb(u);
shuffle(tmp.begin(),tmp.end(),rng);
for(int u:tmp) if(chk(u)) return u;
return -1;
}