和轩少一起Virtual participation了这次比赛,A题读错题花了大量时间导致只有4题就滚粗了。
题意:让你猜一个位置x,范围在1-m,每次你询问系统y,如果x<y,系统会回答-1,x=y回答0,x>y回答1,但是系统有可能会说假话,你只知道系统真假性的回答是周期n(n<=30),要求在至多60次询问找到 x 的值。(回答0肯定是真话)
思路:首先要把一个周期内把系统真假话给测出来,我先问系统n次 1,如果回答-1肯定是假话,回答 1 肯定是假话,接下来就可以直接二分答案了。
#include<bits/stdc++.h>
using namespace std;
int a[50];
int main()
{
int n,m,k,p=-1;
cin>>n>>k;
for(int i=0;i<k;i++)
{
puts("1");
cin>>a[i];
if(a[i]==0)return 0;
}
int l=1,r=n,x;
while(l<=r)
{
m=(l+r)/2;
p++;
p%=k;
cout<<m<<endl;
cin>>x;
if(x==0)
return 0;
x=x*a[p];
if(x==-1)r=m;
else l=m+1;
}
}
题意:有n个数,你可以每个数有无数个,你可以任意选择一些数相加,再模 k 得到一个值d,求出所有不同的d,并且从小到大输出,
思路:其实很好想,假设我有无数个5和7,显然我可以得到的所有的d(0到k-1),因此只要求出这n个数的gcd就行了(直觉告诉我这是对的),d的值是gcd的倍数。
#include<bits/stdc++.h>
using namespace std;
int gcd(int a,int b)
{
if(!b)return a;
return gcd(b,a%b);
}
int main()
{
int n,k,x;
scanf("%d%d",&n,&k);
int tmp=k;
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
tmp=gcd(tmp,x);
}
printf("%d\n",k/tmp);
for(int i=0;i*tmp<k;i++)
printf("%d ",i*tmp);
}
题意:有一颗n个节点的二叉树,每个叶子节点都有一个值(0或1),每个非叶子节点有一个位运算符号,假设节点 o 的位运算符号为 AND,那么 o 的值为左儿子的值 and 右儿子的值,依次求出叶子节点改变后(0变成1,1变成0),根节点1的值,每次叶子节点值改变是独立的。
思路:这个点有点意思,建立好二叉树后,我把每个节点都用 rt[ o ][ v] 标记,这个数组表示这个节点的值为 v 时,根节点的值是多少,这样我搜索的时候就自带记忆化,每次我从叶子节点往上搜索,搜到一个节点,要么是根,要么有标记就结束搜索,并且把得到的答案传给这条路径的所有节点,复杂度降低为n。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int tp[maxn],s[maxn][2],val[maxn],ans;
int f[maxn],rt[maxn][2],vis[maxn],flag[maxn];
char op[10];
void dfs(int o)
{
if(s[o][0])dfs(s[o][0]);
if(s[o][1])dfs(s[o][1]);
if(tp[o]==1)
val[o]=val[s[o][0]]&val[s[o][1]];
else if(tp[o]==2)
val[o]=val[s[o][0]]|val[s[o][1]];
else if(tp[o]==3)
val[o]=val[s[o][0]]^val[s[o][1]];
else if(tp[o]==4)
val[o]=!val[s[o][0]];
}
void dfs2(int o,int v,int son)
{
int fv;
if(tp[o]==1)
fv=v&val[s[o][!son]];
else if(tp[o]==2)
fv=v|val[s[o][!son]];
else if(tp[o]==3)
fv=v^val[s[o][!son]];
else if(tp[o]==4)
fv=!v;
if(o==1||rt[o][fv]!=-1)
{
if(rt[o][fv]==-1)
rt[o][fv]=fv;
ans=rt[o][fv];
return;
}
dfs2(f[o],fv,flag[o]);
rt[o][fv]=ans;
}
int main()
{
int n,u,v;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",op);
rt[i][0]=rt[i][1]=-1;
if(op[0]=='A')
{
scanf("%d%d",&u,&v);
tp[i]=1;
s[i][0]=u,s[i][1]=v;
f[u]=i,f[v]=i,flag[v]=1;
}
else if(op[0]=='O')
{
scanf("%d%d",&u,&v);
tp[i]=2;
s[i][0]=u,s[i][1]=v;
f[u]=i,f[v]=i,flag[v]=1;
}
else if(op[0]=='X')
{
scanf("%d%d",&u,&v);
tp[i]=3;
s[i][0]=u,s[i][1]=v;
f[u]=i,f[v]=i,flag[v]=1;
}
else if(op[0]=='N')
{
scanf("%d",&u);
tp[i]=4;
s[i][0]=u;
f[u]=i;
}
else
{
scanf("%d",&u);
val[i]=u;
vis[i]=1;
}
}
dfs(1);
for(int i=1;i<=n;i++)
if(vis[i])
{
ans=-1;
dfs2(f[i],!val[i],flag[i]);
printf("%d",ans);
}
}