P5635 【CSGRound1】天下第一

P5635 【CSGRound1】天下第一 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

思路:记忆化搜索,因为模数 p p p对于多组输入来说是不变的,那么 ( x + y ) (x + y)%p == 0 (x+y)这个判定条件在整个程序中都是正确的。

题目中,每两个回合是一轮 - 两人都执行一次。为了让代码好写,每次搜索时是按照一轮来搜索。

  • f [ x ] [ y ] ! = 0 f[x][y] != 0 f[x][y]!=0:之前搜索时已经得到答案,直接返回即可
  • f [ x ] [ y ] = = 0 f[x][y] == 0 f[x][y]==0
    • x = 0 x = 0 x=0 x x x一方赢,对 f [ x ] [ y ] f[x][y] f[x][y]进行赋值后返回结果
    • y = 0 y = 0 y=0 y y y一方赢,对 f [ x ] [ y ] f[x][y] f[x][y]进行赋值后返回结果
    • x ! = 0 x != 0 x!=0 y ! = 0 y != 0 y!=0:当前不能得到结果,先赋值 − 1 -1 1,后进行搜索,并将搜索到的值赋给 f [ x ] [ y ] f[x][y] f[x][y]

注意: f [ 1000 ] [ 1000 ] f[1000][1000] f[1000][1000] 1 e 8 1e8 1e8,int型开不下。但是可以知道无论怎样操作,值不会大于 p p p,而 p < 10000 p < 10000 p<10000。因此可以用short来开这个二维数组。

代码如下:

#include 
using namespace std;
short f[10021][10021];
int main()
{
    int t,p; cin>>t>>p;
    while(t--) {
        int x,y; cin>>x>>y;
        auto dfs = [&](auto &&self, int x, int y) -> int {
            if(f[x][y]) return f[x][y];
            if(x == 0) return f[x][y] = 1;
            if(y == 0) return f[x][y] = 2;
            f[x][y] = -1;
            return f[x][y] = self(self, (x + y) % p, ( (x + y) % p + y) % p);
        };
        int ret = dfs(dfs, x, y);
        if(ret == -1) cout<<"error\n";
        else if(ret == 1) cout<<"1\n";
        else cout<<"2\n";
    }
}

你可能感兴趣的:(算法题,算法,数据结构,c++)