F. Chat Screenshots

这里提供一个不用拓扑排序并且容易理解的贪心做法
常年没用过拓扑排序的蒟蒻实在是没想到用拓扑排序,其实如果不使用拓扑排序的话,这个题完全可以是绿的思维难度,首先观察样例,发现对于第一个给出的快照,除了作者之外的所有人的顺序就是定了的,也就是需要作者插入一个地方即可,那么我们可以顺着这个思路来做,对于第一个给出的快照,我们记录作者,并且把后面所有人的顺序记下来,然后进行模拟,只需要记录第一个作者之前的人的位置即可,直接插入到那个人之后就可以了,如果这个人的位置比作者之前的原定的位置还要靠前就不考虑,因为第一步已经定顺序了。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10, mod = 1e9 + 7;
int tot;
void solve(){

    int n, k; cin >> n >> k;

    int f = 0;
    vector<int> p(n + 1);
    vector<vector<int>> a(k + 1, vector<int> (n + 1));
    for(int i = 1; i <= k; i++){
        for(int j = 1; j <= n; j++) cin >> a[i][j];
        if(i == 1){
            f = a[1][1];
            for(int j = 2; j <= n; j++) p[j - 1] = a[i][j];
        } else{
            int pos = 0;
            for(int j = 1; j <= n - 1; j++){
                if(a[i][j + 1] == f){
                    pos = j;
                    break;
                }
            }
            auto it1 = find(p.begin(), p.end(), f);
            if(it1 != p.end()) p.erase(it1);
            auto it2 = find(p.begin(), p.end(), a[i][pos]) + 1;
            if(pos == 1){
                if(it1 == p.end()) p.insert(p.begin() + 1, f);
                else p.insert(it1, f);
            }
            else{
                if(it1 != p.end() && it1 > it2) p.insert(it1, f);
                else p.insert(it2, f);
            }
        }
    }

    auto it = find(p.begin(), p.end(), f);
    if(it == p.end()) p.insert(p.begin() + 1, f);

    for(int i = 1; i <= k; i++){
        vector<int> tmp = p;
        tmp.erase(find(tmp.begin(), tmp.end(), a[i][1]));
        for(int j = 2; j <= n; j++){
            if(tmp[j - 1] != a[i][j]){
                cout << "NO" << '\n';
                return;
            }              
        }
    }    
    
    cout << "YES" << '\n';

}
signed main(){
    std::ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);int t;cin>>t;while(t--)solve();
}

posted @ 2024-11-04 18:54  o-Sakurajimamai-o  阅读(18)  评论(0)    收藏  举报
-- --