D2. RPD and Rap Sheet (Hard Version)

题目链接:https://codeforces.com/contest/1543/problem/D2

题意:

交互题,猜密码,设当前的密码为 \(x\) (不知道是多少)(保证初始密码在 0~n-1 之间),每次输入一个数 \(y\) 表示你猜的密码,若猜错,则密码变为 \(z,z\) 满足\({x}{\oplus_k}{z}=y\),我们将 \({\oplus_k}\) 定义为:\(a{\oplus_k}b=a\) 的 k 进制表示下的每一位与 \(b\) 的 k 进制下的对应位做模 k 加法之后得到的 k 进制数。

\(t\) 组测试样例,每组样例首先给定 \(n,k\) ,即你有 \(n\) 次猜密码的机会,每次猜错后密码 \(x\) 会变为 \(z,{x}{\oplus_k}{z}=y\)\(y\) 为你当前猜的密码。每次输出一个数来猜密码,若猜对则裁判程序会输入 1,然后直接进入下一组测试样例,若猜错则裁判程序会输入 0,继续猜直到猜对或达到次数限制。对于每组测试样例,若你都能在给定的 \(n\) 次次数限制内猜对密码,则通过。

思路:

对于上一题简单版本,我们通过模二加法和模二减法等价,且都等价于异或这个性质,在每一轮查询中使用 \(i\oplus(i-1)\) 匹配上了答案,这更像是猜出来的,因此我们现在来考虑通式。

现在我们来总体地考虑每一轮密码的通式,我们知道当我们当前查询为 y 且查询失败时,下一轮的密码 z 满足 \({x}{\oplus_k}{z}=y\),因为 \({x}{\oplus_k}{z}\) 是对 x 和 z 在转换成 k 进制之后对每一位做模 k 加法,根据模 k 加法和模 k 减法的性质,我们可以类似地定义 \({a}{\ominus_k}{a}\) 为 a 和 b 在转换成 k 进制之后对每一位做模 k 减法,这样由模加和模减的性质我们可以得到:\({x}{\oplus_k}{z}=y \rightarrow z=y{\ominus_k}x\),且易验证 \(\oplus_k\)\(\ominus_k\) 与模加和模减一样满足交换律、结合律以及负负得正等特性,即下一轮密码就等于(当前我们猜测的密码 \(\ominus_k\) 当前密码),我们再设我们每一轮的查询为 \(q_i\),由此我们可以得到每一轮密码的通式:

轮数 1 2 3 4 ... n
密码 x \(q_1{\ominus_k}x\) \(q_2{\ominus_k}(q_1{\ominus_k}x)\) \(q_3{\ominus_k}(q_2{\ominus_k}(q_1{\ominus_k}x))\) ... \(q_{n-1}{\ominus_k}(q_{n-2}{\ominus_k}...{\ominus_k}(q_2{\ominus_k}(q_1{\ominus_k}x))...)\)
查询 \(q_1\) \(q_2\) \(q_3\) \(q_4\) ... \(q_n\)

我们将负负得正的性质带入得:

轮数 1 2 3 4 ... n(n 为偶数)
密码 x \(q_1{\ominus_k}x\) \(q_2{\ominus_k}q_1{\oplus_k}x\) \(q_3{\ominus_k}q_2{\oplus_k}q_1{\ominus_k}x\) ... \(q_{n-1}{\ominus_k}q_{n-2}{\oplus_k}...{\ominus_k}q_2{\oplus_k}q_1{\ominus_k}x\)
查询 \(q_1\) \(q_2\) \(q_3\) \(q_4\) ... \(q_n\)
轮数 1 2 3 4 ... n(n 为奇数)
密码 x \(q_1{\ominus_k}x\) \(q_2{\ominus_k}q_1{\oplus_k}x\) \(q_3{\ominus_k}q_2{\oplus_k}q_1{\ominus_k}x\) ... \(q_{n-1}{\ominus_k}q_{n-2}{\oplus_k}...{\oplus_k}q_2{\ominus_k}q_1{\oplus_k}x\)
查询 \(q_1\) \(q_2\) \(q_3\) \(q_4\) ... \(q_n\)

我们得到了每一轮密码的通式,现在我们要构造的就是查询的通式,而我们的目标是:对于第 i=1~n 轮,每一轮我们都让 i-1 去匹配了 x,我们可以根据此目标来构造查询:对于第一轮,我们令\(q_1=0\),即第一轮用 0 去匹配了 x,然后后面每轮根据密码去构造,如下表所示:

轮数 1 2 3 4 ...
密码 \(\color{red}{x}\) \(0{\ominus_k}{\color{red}{x}}\) \((0{\ominus_k}1){\ominus_k}0{\oplus_k}{\color{red}{x}}\) \(((0{\ominus_k}1){\ominus_k}0{\oplus_k}2){\ominus_k}(0{\ominus_k}1){\oplus_k}0{\ominus_k}{\color{red}{x}}\) ...
查询 \(\color{red}{0}\) \(0{\ominus_k}{\color{red}{1}}\) \((0{\ominus_k}1){\ominus_k}0{\oplus_k}{\color{red}{2}}\) \(((0{\ominus_k}1){\ominus_k}0{\oplus_k}2){\ominus_k}(0{\ominus_k}1){\oplus_k}0{\ominus_k}{\color{red}{3}}\) ...

按运算律化简得:

轮数 1 2 3 4 ...
密码 \({\color{red}{x}}\) \(0{\ominus_k}{\color{red}{x}}\) \({\color{red}{x}}{\ominus_k}1\) \(2{\ominus_k}{\color{red}{x}}\) ...
查询 \({\color{red}{0}}\) \(0{\ominus_k}{\color{red}{1}}\) \({\color{red}{2}}{\ominus_k}1\) \(2{\ominus_k}{\color{red}{3}}\) ...

显然,我们可以得到查询的通式:

轮数 1 2 3 4 ... n
密码 \({\color{red}{x}}\) \(0{\ominus_k}{\color{red}{x}}\) \({\color{red}{x}}{\ominus_k}1\) \(2{\ominus_k}{\color{red}{x}}\) ... \(\begin{cases} {{\color{red}{x}}{\ominus_k}(n-2)},&n为奇数 \\ {(n-2){\ominus_k}{\color{red}{x}}},&n为偶数 \end{cases}\)
查询 \({\color{red}{0}}\) \(0{\ominus_k}{\color{red}{1}}\) \({\color{red}{2}}{\ominus_k}1\) \(2{\ominus_k}{\color{red}{3}}\) ... \(\begin{cases} {{\color{red}{(n-1)}}{\ominus_k}(n-2)},&n为奇数 \\ {(n-2){\ominus_k}{\color{red}{(n-1)}}},&n为偶数 \end{cases}\)

模拟一下\({\ominus_k}\),按查询通式输出即可。

代码:

#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
ll bitmodsub(ll a, ll b, ll k)
{
    ll ans = 0, cur = 1;
    while (a || b) //枚举位,然后进行模减,再累加到结果
    {
        ll t = (a % k - b % k + k) % k; //当前位模减
        a /= k, b /= k;
        ans += (t * cur); //答案加上当前位在k进制下的值
        cur *= k;
    }
    return ans; //返回结果
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    ll t;
    cin >> t;
    while (t--)
    {
        ll n, k, r;
        cin >> n >> k;
        cout << 0 << endl;
        cin >> r;
        ll cnt = 1;
        while (!r)
        {
            if (cnt & 1)
                cout << bitmodsub(cnt - 1, cnt, k) << endl;
            else
                cout << bitmodsub(cnt, cnt - 1, k) << endl;
            cnt++;
            cin >> r;
        }
    }
}

总结:

posted @ 2021-07-09 11:23  Wajor  阅读(128)  评论(0)    收藏  举报