首页 > 其他分享 >CF1906C Cursed Game 题解

CF1906C Cursed Game 题解

时间:2024-07-29 10:20:32浏览次数:17  
标签:int 题解 询问 矩阵 Cursed Game include 交互

题目大意

交互库有一个 \(3\times 3\) 的 01 矩阵 \(a\),每次询问一个 \(n\times n\) 的 01 矩阵 \(b\),交互库会返回一个 \((n-2)\times (n-2)\) 的 01 矩阵 \(c\),满足:

\[c_{x,y} = \bigoplus\limits_{1 \le i,j \le 3} \left ( a_{i,j} \operatorname{AND} b_{x+i-1,y+j-1} \right ) \]

如果一次询问后 \(c\) 矩阵内所有元素全都是 \(1\),你就获胜了。否则,交互库会告诉你 \(c\) 矩阵。保证 \(n\) 是奇数

题解

因为平均下来一组数据只有 \(3\) 次询问,所以我们不能太依赖于交互库,考虑直接把 \(a\) 求出,然后构造矩阵 \(b\)。

如何得到矩阵 \(a\)?可以在 \(b\) 的某个位置填 \(1\),这样就可以得到 \(a\) 哪些位置为 \(1\)。

具体地,对于 \(n\ge 5\),我们可以构造一个矩阵 \(b\) 满足 \(b_{3,3}=1\),其余位置为 \(0\)。那么得到的矩阵 \(c\) 就有 \(c_{i,j}=a_{3-i+1,3-j+1}=a_{4-i,4-j}\),这样就通过一次询问求出了 \(a\)。

然后需要根据 \(a\) 来构造 \(b\)。我们找到最大的 \(x,y\) 使得 \(a_{x,y}=1\)(满足 \(a_{x,y}\) 的右下部分没有 \(1\) 即可)。然后从左上到右下枚举 \(b_{i,j}\),对于一个位置 \(b_{i,j}\),若生成的 \(c_{i,j}=0\),就将 \(b_{i+x-1,j+y-1}\) 取反,就能使 \(c_{i,j}=1\),且不会影响 \(c_{i,j}\) 左上角的数。

因为不同的 \(b_{i,j}\) 对应的 \(b_{i+x-1,j+y-1}\) 肯定是不同的,所以这样子依次改下去,就能使整个 \(b\) 符合条件。

对于 \(n<5\),即 \(n=3\) 时,返回值只有 \(1\) 个数,不能得到很好的信息。所以可以考虑直接随机,因为只有 \(0\) 和 \(1\) 两种可能,所以随机的正确率为 \(\frac 1 2\)。

对于 \(n \ge 5\) 的情况,共需要 \(2\) 次询问。而 \(n=3\) 时,期望用 \(2\) 次询问,所以 \(999\) 次询问时绰绰有余的。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <random>
#define ll long long
using namespace std;
const int N = 40;
int a[4][4],b[N][N],c[N][N],n;
mt19937 rnd(114514);
bool pri()
{
    for(int i = 1;i <= n;i++)
    {
        for(int j = 1;j <= n;j++)cout << b[i][j];
        cout << endl;
    }
    string s;cin >> s;
    return s[0]=='C';
}
int get(int i,int j)
{
    bool sum = 0;
    for(int x = 1;x <= 3;x++)for(int y = 1;y <= 3;y++)
        sum ^= a[x][y]&b[i+x-1][j+y-1];
    return sum;
}
inline int rd()
{
    char c;int f = 1;
    while(!isdigit(c = getchar()))if(c=='-')f = -1;
    int x = c-'0';
    while(isdigit(c = getchar()))x = x*10+(c^48);
    return x*f;
}
int main()
{
    // freopen(".in","r",stdin);
    // freopen(".out","w",stdout);
    int t = 333;
    while(t--)
    {
        memset(a,0,sizeof a);memset(b,0,sizeof b);
        n = rd();
        if(n == 3)
        {
            while(1)
            {
                for(int i = 1;i <= n;i++)for(int j = 1;j <= n;j++)
                    b[i][j] = rnd()&1;
                if(pri())break;else rd();
            }
            continue;
        }
        b[3][3] = 1;
        if(pri())continue ;
        for(int i = 1;i <= n-2;i++)
        {
            string s;cin >> s;
            if(i <= 3)
                for(int j = 1;j <= 3;j++)
                    a[4-i][4-j] = s[j-1]-'0';
        }
        int x = 0,y = 0;
        for(int i = 1;i <= 3;i++)for(int j = 1;j <= 3;j++)
            if(a[i][j])x = i,y = j;
        for(int i = 1;i <= n-2;i++)for(int j = 1;j <= n-2;j++)
            if(!get(i,j))b[i+x-1][j+y-1] ^= 1;
        pri();
    }
    return 0;
}

标签:int,题解,询问,矩阵,Cursed,Game,include,交互
From: https://www.cnblogs.com/max0810/p/18329476

相关文章

  • 梦熊十三连测第三场题解
    T1本题考察了数论的相关知识。30pts暴力枚举每次洗牌的情况,时间复杂度为\(O(n^2)\)。60pts首先卡牌\(1\)和\(2n\)一直不动,可以不用考虑这两张牌。将位置和剩下的牌上的数字全减\(1\),那么数字为\(k\)的牌操作一次后就会到\(2k\bmod(2n-1)\)的位置。那么问题相当......
  • Maximum Glutton题解
    正常动规,但是赛时死了。分析看到\(n\)很小,但是\(X\)和\(Y\)有点大,所以状态稍微改变一下。设\(dp_{i,j}\)表示已经选到第\(j\)个,且甜度为\(i\)时咸度的最小值。转移方程为:\[dp_{j,k}=\min_{0\lek\lei,a_i\lej\leX}(dp_{j,k},dp_{j-a_i,k-1}+b_i)\]按照\(i,j......
  • pygame 文件调用 Pygame 文件时出现 MouduleNotFound 错误
    我遇到的错误如下:ModuleNotFoundError:Nomodulenamed'pygame.rect'我将错误追溯到sprite.py(一个pygame文件),它试图导入文件rect.py。这是我的文件路径:文件路径白色圈出的文件是尝试导入“rect.py”的文件。我能找到的唯一类似文件是用红色圈出的文件“r......
  • CF526G Spiders Evil Plan 题解
    Description给定一棵\(n\)个节点的无根树,每条边有边权。有\(q\)次询问,每次询问给出\(x,y\),你需要选择\(y\)条树上的路径,使这些路径形成一个包含\(x\)的连通块,且连通块中包含的边权和最大。\(n,q\le10^5\),强制在线。Solution考虑只有一组询问怎么快速求答案。容......
  • 【科大讯飞笔试题汇总】2024-07-27-科大讯飞秋招提前批(研发岗)-三语言题解(Cpp/Java/
    ......
  • ABC364 DEF 题解
    ABC364DEF题解D-K-thNearest题目链接赛时想了一个(也许确实是对的)做法,但是代码太难写,一直没写出来……看了官方题解才发现正解其实也很简单……本题最关键的一点是要转换思路:与其考虑“离某个点第\(k\)近的点在哪”,不如考虑“离某个点距离不超过\(x\)的点有多少个”。......
  • 会员购项目面试题解析:高效数据抓取与异常处理
    会员购项目亮点日志记录信息协程异步抓取数据,大大提高抓取速度捕获异常,并添加重试机制源码importloggingimporttimeimportrequestsimportasyncioimportaiohttpfromaiohttpimportContentTypeErrorimportcsv#配置日志logging.basicConfig(level=logging......
  • C++题解(17) 狐猬编程: 640.线段覆盖
    题目描述在一条数轴上,有N条线段,第i条线段的左端点是s[i],右端点是e[i]。如果线段有重叠(即使是端点重叠也算是重叠),则输出“impossible”,如果没有重叠则输出“possible”。输入格式输入文件名:640.in多组测试数据。第一行,一个整数G,表示有G组测试数据。1<=G<=10。每组......
  • [题解]ABC364 A~F
    A-GluttonTakahashi给定\(n\)道菜,每道菜要么是甜的(用sweet表示),要么是咸的(用salty表示)。必须按顺序吃,如果连续吃到\(2\)个甜的菜,就会浑身难受吃不下去了。请问是否能吃完这些菜。按题意模拟即可,只要前\(n-1\)个元素中有连续的sweet就输出No。点击查看代码#include<bits/s......
  • CF292D 题解
    \(O(mk\alpha(n))\)暴力,考虑对于每个询问\(l,r\),枚举\(1\siml-1,r+1\simm\),并查集连边即可。1154ms。\(O(n(m+k\alpha(n)))\)我们发现枚举\(i\in[1,l),j\in(r,m]\)太慢了。考虑先预处理出并查集从\(1\)连边到编号为\(id\)的边的状态\(pre_{id}\),倒过来再处理出......