sairate c9f8710d03 sairate<sairate@sina.cn>
Signed-off-by: sairate <sairate@sina.cn>
2025-07-12 16:05:52 +08:00

107 lines
2.1 KiB
C++

/*
NOI 2002 Day 1 Problem 2
Child
Sample Solution
by Rujia Liu
*/
#include "childlib.cpp"
#define MaxN 502
int N,M,C,Tot;
int Next[MaxN];
int ChildType[MaxN];
int Possible[MaxN];
int NTried[MaxN];
int Tried[MaxN][5];
//This is a Time-Space Trade off. This uses less memory but a lot of time
int CalcChildType(int Ref)
{
int a,b;
a=Ref;
ChildType[Ref]=0;
while(a%C+1!=Ref){
b=a%C+1;
if(ChildType[a]==0) ChildType[b]=1-Next[a];
else ChildType[b]=Next[a];
a=b;
}
if (ChildType[a]==0 && Next[a]==1) return 0;
if (ChildType[a]==1 && Next[a]==0) return 0;
ChildType[Ref]=2;
return 1;
}
void PreProcess(void)
{
int i,j,Num1,Num2;
GetNM(&N,&M);
C=N+M+1;
for(i=1;i<=C;i++) Next[i]=Ask(i,i%C+1,0);
Tot=0;
for(i=1;i<=C;i++){
if(!CalcChildType(i)) continue;
Num1=0; Num2=0;
for(j=1;j<=C;j++){
if(ChildType[j]==0) Num1++;
if(ChildType[j]==1) Num2++;
}
if (Num1==N && Num2==M){
Possible[i]=1;
Tot++;
}
else Possible[i]=0;
}
}
void Sieve(void)
{
int i,j,k,t,Turn;
int ok;
int Result;
for(i=1;i<=C;i++){
NTried[i]=2;
Tried[i][1]=i;
Tried[i][2]=i%C+1;
}
for(Turn=0;Turn<5;Turn++)
for(i=1;i<=C;i++){
if (Tot==1)
for (k=1;k<=C;k++)
if (Possible[k]){
CalcChildType(k);
for(t=1;t<=C;t++) Answer(ChildType[t]);
}
//Find a person to Ask about
for(j=1;j<=C;j++){
ok=1;
for(k=1;k<=NTried[i];k++)
if(j==Tried[i][k]) ok=0;
if (ok) break;
}
//Test Every Possibility
Result=Ask(i,j,0);
for(k=1;k<=C;k++)
if (Possible[k]){
CalcChildType(k);
if (ChildType[i]==0 || (ChildType[i]==2 && NTried[i]%2==1)){ //Say Truth
if (Result==0 && ChildType[j]==0) Possible[k]=0;
if (Result==1 && ChildType[j]!=0) Possible[k]=0;
}
if (ChildType[i]==1 || (ChildType[i]==2 && NTried[i]%2==0)){
if (Result==0 && ChildType[j]!=0) Possible[k]=0;
if (Result==1 && ChildType[j]==0) Possible[k]=0;
}
if(!Possible[k]) Tot--;
}
NTried[i]++;
Tried[i][NTried[i]]=j;
}
}
void main()
{
PreProcess();
Sieve();
}