1 条题解
-
0
自动搬运
来自洛谷,原作者为

入门题杀手
* *搬运于
2025-08-24 22:23:21,当前版本为作者最后更新于2020-12-02 13:59:58,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
P6720
异或的性质:
- → 且
对于数列 ,已知:
-
=
-
=
-
= =
-
= = =
-
= = =
-
.......
即发现除 外,数列 呈周期性:
- =
且至多由 个元素组成: 、 、 、 。
( 很特殊只在第一位出现,所以说放在最后处理)。
同时函数 是一个双射,即保证对于:
, →
若第 次询问与第 次询问返回的值 相同,
且此时的 与 的值不同,即是 :
=
则可知:
=
移项可得:
=
、 为输入(已知)的, 、 可转化为 、 、 中的两个,
那么此时的可求,同理可求出 、 、 。
代码实现.cpp:
第一次询问 ,记录 的值:
printf("0\n"); cout.flush(); int TMP; scanf("%d",&TMP);当 不确定时,第 次询问 询问次数 即 ,
数组 的脚标可表示为: 。
定义值域数组 表示当 为 时的询问次数 即为 。
for(int i=0; i<256; i++) { printf("%d\n",i); cout.flush(); scanf("%d",k+i); if(pos[k[i]]!=-1)//表示大小为k[i]的值已经出现过了 R[find(i%3+1,pos[k[i]]%3+1)]=(i^(pos[k[i]])); // R[k]=R[i]^R[j]=A[i]^A[j] pos[k[i]]=i; tot=i; if(check()) break; }如果 、 、 中已知两个,就可以异或起来推出另一个,退出循环;
此时就可以构造出函数 的脚标,定向求出未知的 :
之前忽略的 也可以在这个时候顺便求出来。for(int i=0; i<256; i++) { if(M[i]==-1) {//说明M[i]还未更新 tot++; printf("%d\n",(R[tot%3+1]^i)); cout.flush(); scanf("%d",M+i); } if(M[i]==TMP) R[0]=i; }由容斥原理可证明,询问次数在 次内一定可会有重复的数字出现,所以能够在要求的次数内询问得到答案。
最后输出的时候记得cout.flush()!详细实现代码附上:
#include<bits/stdc++.h> using namespace std; int R[5]= {-1,-1,-1,-1},M[333];//RT int pos[333],k[333],tot; inline int find(int x,int y) {//输入1、2、3中的两个返回另一个 for(int i=1; i<=3; i++) if(i!=x&&i!=y) return i; } inline bool check() {//判断退出条件 int tmp=0; for(int i=1; i<=3; i++) tmp+=(R[i]==-1);//判断R[]有几个已求出 if(tmp==1) { if(R[1]==-1) R[1]=R[2]^R[3];//若有两个R[]已经求出,即可推出第三个R[] if(R[2]==-1) R[2]=R[1]^R[3]; if(R[3]==-1) R[3]=R[1]^R[2]; } return (tmp<=1); } int main() { memset(M,-1,sizeof(M));//由于数据有0 需要初始化 memset(pos,-1,sizeof(pos)); printf("0\n"); cout.flush(); int TMP; scanf("%d",&TMP); for(int i=0; i<256; i++) { printf("%d\n",i); cout.flush(); scanf("%d",k+i); if(pos[k[i]]!=-1) R[find(i%3+1,pos[k[i]]%3+1)]=(i^(pos[k[i]])); pos[k[i]]=i; tot=i; if(check()) break; } for(int i=0; i<=tot; i++) M[(i^R[i%3+1])]=k[i]; for(int i=0; i<256; i++) { if(M[i]==-1) { tot++; printf("%d\n",(R[tot%3+1]^i)); cout.flush(); scanf("%d",M+i); } if(M[i]==TMP) R[0]=i; } printf("SOLUTION\n"); cout.flush(); for(int i=0; i<=2; i++) { printf("%d\n",R[i]); cout.flush(); } for(int i=0; i<256; i++) { printf("%d\n",M[i]); cout.flush(); } return 0; }
- 1
信息
- ID
- 5749
- 时间
- 100ms
- 内存
- 64MiB
- 难度
- (无)
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者