交互题合集
简介
交互题是一种有趣的题目类型,题目一般会有一个目标值,如数组和,数组中的最大值等,为了求出这个目标值,允许进行限制次数的指定类型的询问,如询问 的值,系统会对每个询问给出结果,这就是交互的过程。在所有询问执行完后需要求出目标值并输出
题目
CF679A.Bear and Prime 100
题目链接:CF679A
题意:有一个在区间 内的未知整数 ,你需要判断它是否为素数。可以进行不超过 次询问,每次可以询问一个由你指定的整数 是否为 的约数
分析:当 为合数时,可以表示为 而 ,所以 ,所以根据算术分解定理, 一定会被小于等于 的素因子整除,枚举可知这样的素因子一共有 个。那么我们进行 次询问,计算 可以被多少个素因子整除,如果被两个或以上的素因子整除,那么 一定是合数,如果只被一个素因子 整除,那么需要判断 的情况,所以再进行一次询问,判断 是否整除 ,若整除则 为合数,否则为素数
#include<bits/stdc++.h>
using namespace std;
int p[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47};
bool query(int x)
{
cout << x << endl;
string s;
cin >> s;
return s == "yes";
}
int main()
{
int sum = 0, div;
for(int i = 0; i < 15; i++) {
if(query(p[i])) {
sum++;
div = p[i];
}
}
if(sum >= 2) {
cout << "composite" << endl;
} else {
if(div > 10)
cout << "prime" << endl;
else
cout << (query(div * div) ? "composite" : "prime") << endl;
}
return 0;
}
CF727C.Guess the Array
题目链接:CF727C
题意:有一个长度为 的未知整数数组,需要求出每个元素的值。可以进行不超过 次询问,每次可以询问 的值
分析:考虑 时如何求解。容易想到询问三次,分别记 那么 ,求出 后再 即可。那么当 大于 时要求 的值只需询问 ,而 已知,这样就解决了问题
#include<bits/stdc++.h>
using namespace std;
int ans[5000 + 5];
int query(int x, int y)
{
cout << "? " << x << ' ' << y << endl;
int res;
cin >> res;
return res;
}
int main()
{
int n;
cin >> n;
int s1 = query(1, 2), s2 = query(1, 3), s3 = query(2, 3);
ans[1] = (s1 + s2 - s3) / 2;
ans[2] = s1 - ans[1];
ans[3] = s3 - ans[2];
for(int i = 4; i <= n; i++)
ans[i] = query(1, i) - ans[1];
cout << '!';
for(int i = 1; i <= n; i++)
cout << ' ' << ans[i];
cout << endl;
return 0;
}
CF1556D.Take a Guess
题目链接:CF1556D
题意:有一个长度为 的未知整数数组,需要求出每个元素的值。可以进行不超过 次询问,每次可以询问 或 的值
分析:可以发现一个恒等式 ,那么用 次询问就可以求得 ,所以就可以转化为上一个问题
#include<bits/stdc++.h>
using namespace std;
int n, k;
int a[10000 + 5];
int query(int x, int y)
{
int res1, res2;
cout << "or " << x << ' ' << y << endl;
cin >> res1;
cout << "and " << x << ' ' << y << endl;
cin >> res2;
return res1 + res2;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n >> k;
int s1 = query(1, 2), s2 = query(1, 3), s3 = query(2, 3);
a[1] = (s1 + s2 - s3) / 2;
a[2] = s1 - a[1];
a[3] = s2 - a[1];
for(int i = 4; i <= n; i++)
a[i] = query(1, i) - a[1];
sort(a + 1, a + n + 1);
cout << "finish " << a[k] << endl;
return 0;
}
CF1451E1.Bitwise Queries
题目链接:CF1451E1
题意:有一个长度为 的未知整数数组,需要求出每个元素的值。可以进行不超过 次询问,每次可以询问 或 或 的值
分析:可以发现这道题是上一道题的加强版,多了一个异或的询问种类。考虑如何用异或降低询问次数,可以先用上一道题的方法求出 的值,对于每个 ,询问 ,而 ,所以只需一次询问即可求出。这样一共用了 次询问,仍不满足要求。考虑另一个恒等式 ,那么我们只要询问 和 就可以得到 ,此时只用了 次询问,再用 次询问 ,总共进行了 次询问,满足要求
#include<bits/stdc++.h>
using namespace std;
int n;
int a[65540];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
int res1, res2, res3, res4, res5;
cout << "AND 1 2" << endl;
cin >> res1;
cout << "AND 1 3" << endl;
cin >> res2;
cout << "XOR 1 2" << endl;
cin >> res3;
cout << "XOR 1 3" << endl;
cin >> res4;
cout << "AND 2 3" << endl;
cin >> res5;
a[1] = (res3 + 2 * res1 + res4 + 2 * res2 - 2 * res5 - (res3 ^ res4)) / 2;
a[2] = 2 * res1 + res3 - a[1];
a[3] = 2 * res2 + res4 - a[1];
for(int i = 4; i <= n; i++) {
int t;
cout << "XOR 1 " << i << endl;
cin >> t;
a[i] = t ^ a[1];
}
cout << '!';
for(int i = 1; i <= n; i++)
cout << ' ' << a[i];
cout << endl;
return 0;
}
CF1207E.XOR Guessing
题目链接:CF1207E
题意:有一个在区间 内的未知整数 ,你可以进行 次询问,每次询问要给出 个在区间 内不同的数字,系统会在这些数中随机挑选一个并回答它与 的异或值,需要求出 的值
分析:由于系统会在给定的数中随机挑选一个回答,那么必须保证给出的任意一个数被挑选时都能得到有用的信息。由于 与任何数的异或值都为那个数,所以考虑在二进制表示下把前 位设为 ,那么询问一定可以得到 前 位的值,那么第二次询问很显然是把后 位设为 ,将两次询问的结果合并即可得到
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int res1, res2;
cout << '?';
for(int i = 1; i <= 100; i++)
cout << ' ' << i;
cout << endl;
cin >> res1;
cout << '?';
for(int i = 1; i <= 100; i++)
cout << ' ' << i * 128;
cout << endl;
cin >> res2;
cout << "! " << res1 / 128 * 128 + res2 % 128 << endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】