Loading

CodeForces-1472F New Year's Puzzle

New Year's Puzzle

模拟

如果尝试从左到右放,就会发现其实放的基本是唯一的,因此考虑直接模拟就好了

针对当前列,分成三种状态:

  1. 状态 \(0\):上下都不能放

  2. 状态 \(1\):下面不能放

  3. 状态 \(2\):上面不能放、

  4. 状态 \(3\):上下都能放

考虑不同的状态相互遇到会变成另一个什么状态,即可

第一行表示遇到的状态,第一列表示当前状态,\(-1\) 表示非法

0 1 2 3
0 0 1 2 0
1 1 0 -1 1
2 2 0 -1 2

模拟的时候,自动取一下奇偶来完成遇到 \(状态3\) 的转换即可

同时在末尾要插入最终的状态,拿一个状态 \(0\) 堵住就可以了

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <array>
using namespace std;
const int dir[3][3] = {0, 1, 2, -1, 0, -1, -1, -1, 0};

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin >> t;
    while(t--)
    {
        int n, m;
        cin >> n >> m;
        vector<array<int, 2> >num(m + 2);
        for(int i=0; i<m; i++)
        {
            int a, b;
            cin >> b >> a;
            num[i] = {a, b};
        }
        num[m] = {n + 1, 1};
        num[m + 1] = {n + 1, 2};
        sort(num.begin(), num.end());
        int st = 0, pre = 1;
        int f = 1;
        for(int i=0; i<num.size() && f; i++)
        {
            int nex_st = 2;
            if(num[i][1] == 1) nex_st = 1;
            if(i < num.size() - 1 && num[i+1][0] == num[i][0]) nex_st = 0;
            int dis = num[i][0] - pre;
            if(dis % 2 == 1 && st) st ^= 2 ^ 1;
            st = dir[st][nex_st];
            if(st == -1) f = 0;
            pre = num[i][0] + 1;
            if(nex_st == 0) i++;
        }
        if(f) cout << "YES\n";
        else cout << "NO\n";
        cout << endl;
    }
    return 0;
}
posted @ 2022-08-16 20:49  dgsvygd  阅读(22)  评论(0编辑  收藏  举报