Submission #1218141
Source Code Expand
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <list>
#include <cassert>
#include <ctime>
#include <climits>
using namespace std;
#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }
const int MAXN=200;
const int MAXM=MAXN-1;
int n,nq;
int locghead[MAXN],locgnxt[2*MAXM],locgto[2*MAXM];
bool local=false;
typedef struct QLOC {
bool alive[MAXN];
int state[MAXN];
int q[MAXN],qhead,qtail,d[MAXN];
int calc() {
int ret=0;
REP(i,n) state[i]=0;
REP(i,n) if(state[i]==0&&alive[i]) {
qhead=qtail=0; q[qhead++]=i,d[i]=0,state[i]=1;
while(qtail<qhead) { int at=q[qtail++]; for(int x=locghead[at];x!=-1;x=locgnxt[x]) { int to=locgto[x]; if(!alive[to]||state[to]==state[at]) continue; q[qhead++]=to,d[to]=d[at]+1,state[to]=state[at]; } }
int j=q[qhead-1];
qhead=qtail=0; q[qhead++]=j,d[j]=0,state[j]=2;
while(qtail<qhead) { int at=q[qtail++]; for(int x=locghead[at];x!=-1;x=locgnxt[x]) { int to=locgto[x]; if(!alive[to]||state[to]==state[at]) continue; q[qhead++]=to,d[to]=d[at]+1,state[to]=state[at]; } }
int k=q[qhead-1],diam=d[k]; ret+=diam*diam;
}
return ret;
}
} QLOC;
QLOC qloc;
bool inq[MAXN];
int query(const vector<int> &now) {
++nq; REP(i,n) inq[i]=false; REPSZ(i,now) inq[now[i]]=true;
if(local) {
REP(i,n) qloc.alive[i]=inq[i]; return qloc.calc();
} else {
printf("? "); REP(i,n) printf("%d",inq[i]?1:0); puts(""); fflush(stdout);
int ret; scanf("%d",&ret); return ret;
}
assert(false); return false;
}
bool can[MAXN][MAXN];
int ghead[MAXN],gnxt[2*MAXM],gto[2*MAXM]; int m;
pair<int,int> ret[MAXM]; int nret;
void found(int a,int b) {
//printf("found(%d,%d)\n",a,b);
ret[nret++]=MP(min(a,b),max(a,b)); can[a][b]=can[b][a]=false;
gnxt[2*m+0]=ghead[a],ghead[a]=2*m+0,gto[2*m+0]=b;
gnxt[2*m+1]=ghead[b],ghead[b]=2*m+1,gto[2*m+1]=a;
++m;
}
void clear(const vector<int> &now) {
REPSZ(i,now) FORSZ(j,i+1,now) { int a=now[i],b=now[j]; can[a][b]=can[b][a]=false; }
}
int q[MAXN],qhead,qtail;
int col[MAXN];
void colorize() {
REP(i,n) col[i]=-1;
REP(i,n) if(col[i]==-1) {
qhead=qtail=0; col[i]=0; q[qhead++]=i;
while(qtail<qhead) { int at=q[qtail++]; for(int x=ghead[at];x!=-1;x=gnxt[x]) { int to=gto[x]; if(col[to]!=-1) continue; col[to]=1-col[at]; q[qhead++]=to; } }
REP(j,qhead) FOR(k,j+1,qhead) { int a=q[j],b=q[k]; can[a][b]=can[b][a]=false; }
}
}
void solve() {
nret=m=nq=0; REP(i,n) REP(j,n) can[i][j]=i!=j; REP(i,n) ghead[i]=-1;
while(true) {
colorize();
int i=-1; int icnt;
REP(ii,n) { int cnt=0; REP(j,n) if(can[ii][j]) ++cnt; if(cnt>0&&(i==-1||cnt>icnt)) i=ii,icnt=cnt; }
if(i==-1) break;
//REP(j,n) printf("%d ",col[j]); puts("");
int curcol=-1; REP(j,n) if(can[i][j]) { curcol=col[j]; break; } assert(curcol!=-1);
vector<int> opt; REP(j,n) if(can[i][j]&&col[j]==curcol) opt.PB(j);
//printf("checking %d with",i); REPSZ(j,opt) printf(" %d",opt[j]); puts("");
vector<int> one;
{ vector<int> now=opt; now.PB(i); int cur=query(now); if(cur==0) { clear(now); continue; } else if(cur==1&&SZ(now)>SZ(one)) one=now; }
int lst;
{
int l=-1,r=SZ(opt)-1;
while(l+1<r) {
int m=l+(r-l)/2;
vector<int> now; REPE(j,m) now.PB(opt[j]); now.PB(i); int cur=query(now); if(cur==0) { clear(now); l=m; } else { r=m; if(cur==1&&SZ(now)>SZ(one)) one=now; }
}
lst=r;
}
{ vector<int> now; now.PB(i); now.PB(opt[lst]); if(lst>0&&!query(now)) clear(now); else { found(i,opt[lst]); clear(one); continue; } }
int fst;
{
int l=0,r=lst;
while(l+1<r) {
int m=l+(r-l)/2;
vector<int> now; FORE(j,m,lst) now.PB(opt[j]); int cur=query(now); if(cur==0) { clear(now); r=m; } else { l=m; if(cur==1&&SZ(now)>SZ(one)) one=now; }
}
fst=l;
}
found(opt[fst],opt[lst]); clear(one);
}
sort(ret,ret+nret);
}
void run() {
scanf("%d",&n);
solve();
printf("!"); REP(i,nret) printf(" (%d,%d)",ret[i].first,ret[i].second); puts(""); fflush(stdout);
}
int locpar[MAXN];
int locperm[MAXN];
pair<int,int> want[MAXM]; int nwant;
bool check() {
nwant=0; REP(i,n) for(int x=locghead[i];x!=-1;x=locgnxt[x]) if(i<locgto[x]) want[nwant++]=MP(i,locgto[x]); sort(want,want+nwant);
if(nwant!=nret) return false; REP(i,nret) if(ret[i]!=want[i]) return false; return true;
}
int num=0,den=0;
bool verify() {
if(check()) { num+=nq,den++; printf("%.0lf ",1.0*num/den); return true; }
printf("have:"); REP(i,nret) printf(" %d-%d",ret[i].first,ret[i].second); puts("");
printf("want:"); REP(i,n) for(int x=locghead[i];x!=-1;x=locgnxt[x]) if(i<locgto[x]) printf(" %d-%d",i,locgto[x]); puts("");
return false;
}
void stress() {
while(true) {
local=true;
n=200;
locpar[0]=-1; FOR(i,1,n) locpar[i]=rand()%i;
REP(i,n) locperm[i]=i; REP(i,n) { int j=i+rand()%(n-i); swap(locperm[i],locperm[j]); }
REP(i,n) locghead[i]=-1;
REP(i,n-1) {
int a=locperm[i+1],b=locperm[locpar[i+1]];
locgnxt[2*i+0]=locghead[a],locghead[a]=2*i+0,locgto[2*i+0]=b;
locgnxt[2*i+1]=locghead[b],locghead[b]=2*i+1,locgto[2*i+1]=a;
}
solve();
if(!verify()) break;
}
}
void debug() {
local=true;
scanf("%d",&n);
REP(i,n) locghead[i]=-1;
REP(i,n-1) {
int a,b; scanf("%d%d",&a,&b);
locgnxt[2*i+0]=locghead[a],locghead[a]=2*i+0,locgto[2*i+0]=b;
locgnxt[2*i+1]=locghead[b],locghead[b]=2*i+1,locgto[2*i+1]=a;
}
solve();
verify();
}
int main() {
//stress();
//debug();
run();
return 0;
}
Submission Info
Submission Time
2017-04-12 23:54:31+0900
Task
H - Huge Kingdom: Atcoder
User
krijgertje
Language
C++14 (GCC 5.4.1)
Score
985
Code Size
6056 Byte
Status
AC
Exec Time
134 ms
Memory
980 KB
Compile Error
./Main.cpp: In function ‘int query(const std::vector<int>&)’:
./Main.cpp:67:28: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
int ret; scanf("%d",&ret); return ret;
^
./Main.cpp: In function ‘void run()’:
./Main.cpp:136:16: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
scanf("%d",&n);
^
./Main.cpp: In function ‘void debug()’:
./Main.cpp:173:16: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
scanf("%d",&n);
^
./Main.cpp:176:31: warning: ignoring return value of ‘int scanf(const char*, ...)’, declared with attribute warn_unused_result [-Wunused-result]
int a,b; scanf("%d%d",&a,&b);
^
Judge Result
Set Name
Text1
Text2
Text3
Text4
Text5
Score / Max Score
197 / 300
196 / 300
197 / 300
197 / 300
198 / 300
Status
Set Name
Test Cases
Text1
in1.txt
Text2
in2.txt
Text3
in3.txt
Text4
in4.txt
Text5
in5.txt
Case Name
Status
Exec Time
Memory
in1.txt
AC
127 ms
976 KB
in2.txt
AC
132 ms
852 KB
in3.txt
AC
130 ms
848 KB
in4.txt
AC
134 ms
980 KB
in5.txt
AC
130 ms
852 KB