交互题合集

简介

交互题是一种有趣的题目类型,题目一般会有一个目标值,如数组和,数组中的最大值等,为了求出这个目标值,允许进行限制次数的指定类型的询问,如询问 ai+aj 的值,系统会对每个询问给出结果,这就是交互的过程。在所有询问执行完后需要求出目标值并输出

题目

CF679A.Bear and Prime 100

题目链接CF679A

题意:有一个在区间 [2,100] 内的未知整数 x ,你需要判断它是否为素数。可以进行不超过 20 次询问,每次可以询问一个由你指定的整数 d 是否为 x 的约数

分析:当 x 为合数时,可以表示为 x=nmn2 ,所以 m50 ,所以根据算术分解定理, x 一定会被小于等于 50 的素因子整除,枚举可知这样的素因子一共有 15 个。那么我们进行 15 次询问,计算 x 可以被多少个素因子整除,如果被两个或以上的素因子整除,那么 x 一定是合数,如果只被一个素因子 p 整除,那么需要判断 x=pq 的情况,所以再进行一次询问,判断 p2 是否整除 x ,若整除则 x 为合数,否则为素数

#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

题意:有一个长度为 n 的未知整数数组,需要求出每个元素的值。可以进行不超过 n 次询问,每次可以询问 ai+aj 的值

分析:考虑 n=3 时如何求解。容易想到询问三次,分别记 s1=a1+a2,s2=a1+a3,s3=a2+a3 那么 2a1=(s1+s2s3) ,求出 a1 后再 a2=s1a1,a3=s2a1 即可。那么当 n 大于 3 时要求 ai 的值只需询问 a1+ai ,而 a1 已知,这样就解决了问题

#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

题意:有一个长度为 n 的未知整数数组,需要求出每个元素的值。可以进行不超过 2n 次询问,每次可以询问 ai|ajai&aj 的值

分析:可以发现一个恒等式 a|b+a&b=a+b ,那么用 2 次询问就可以求得 ai+bi ,所以就可以转化为上一个问题

#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

题意:有一个长度为 n 的未知整数数组,需要求出每个元素的值。可以进行不超过 n+2 次询问,每次可以询问 ai|ajai&ajaiaj 的值

分析:可以发现这道题是上一道题的加强版,多了一个异或的询问种类。考虑如何用异或降低询问次数,可以先用上一道题的方法求出 a1,a2,a3 的值,对于每个 i>3 ,询问 aia1 ,而 ai=aia1a1 ,所以只需一次询问即可求出。这样一共用了 n3+6=n+3 次询问,仍不满足要求。考虑另一个恒等式 ab+2a&b=a+b ,那么我们只要询问 a1a2a1a3 就可以得到 a2a3 ,此时只用了 2 次询问,再用 3 次询问 a1&a2,a1&a3,a2&a3 ,总共进行了 n3+5=n+2 次询问,满足要求

#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

题意:有一个在区间 [0,2141] 内的未知整数 x ,你可以进行 2 次询问,每次询问要给出 100 个在区间 [0,2141] 内不同的数字,系统会在这些数中随机挑选一个并回答它与 x 的异或值,需要求出 x 的值

分析:由于系统会在给定的数中随机挑选一个回答,那么必须保证给出的任意一个数被挑选时都能得到有用的信息。由于 0 与任何数的异或值都为那个数,所以考虑在二进制表示下把前 7 位设为 0 ,那么询问一定可以得到 x7 位的值,那么第二次询问很显然是把后 7 位设为 0 ,将两次询问的结果合并即可得到 x

#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;
}
posted @   f(k(t))  阅读(681)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示