标签:pop rgb enter color pac 匹配 链接 style force
题目链接:https://codeforces.com/contest/1476/problem/E
题目大意:给你n个模式串和m个字符串(长度都为k),要求你将模式串进行排序使得每个字符串在排序后的模式串中第一个匹配的是未排序前的模式串中第mt个模式串。对于模式串和字符串 如果对于1~k 字符串中第i个字符串==模式串中第i个字符或者模式串中第i个字符为‘_‘,则称之为匹配。
解题思路:我们可以给每个模式串进行编号(1~n,因为模式串间互不相同)。我们可以考虑每个每个字符串所匹配的模式串的编号,如果匹配的模式串的编号中不存在mt,则无解。否则我们可以建一个有向无环图,对于每一个字符串,编号为mt的模式串要在其他所有编号之前。因此我们可以从mt向其他编号连边,表示mt在其他编号之前。然后拓扑求解即可。
#include<bits/stdc++.h> using namespace std; const int maxn = 1e5+10; const int maxn2 = 1e5+10; const int inf = 0x3f3f3f3f-1; bool check(int i,int d){ while(i){ if(i%10==d){ return true; } i/=10; } return false; } typedef long long ll; int ans[maxn],deg[maxn]; vector<int>g[maxn]; int n,m,k; bool topsort(){ queue<int>q; for(int i=1;i<=n;i++) { if(deg[i]==0) q.push(i); } int count = 0; while(!q.empty()){ int t = q.front(); q.pop(); ans[++count] = t; for(auto id:g[t]){ deg[id]--; if(deg[id]==0) q.push(id); } } if(count!=n) return false; return true; } int main(){ bool ok = true; cin>>n>>m>>k; vector<string>p(n+5); map<string,int>mp; for(int i=1;i<=n;i++){ cin>>p[i]; mp[p[i]] = i; } for(int i=1;i<=m;i++){ string s; int mt; cin>>s>>mt; vector<int>temp; string stemp = s; for(int j=0;j<(1<<k);j++){ int cnt = 0 ; int flag = j; while(flag){ if(flag&1) s[cnt] = ‘_‘; cnt++; flag>>=1; } if(mp[s]!=0){ temp.push_back(mp[s]); } // cout <<s<<endl; s=stemp; } if(!count(temp.begin(),temp.end(),mt)) { ok = false; } for(auto id:temp){ if(id!=mt){ g[mt].push_back(id); deg[id]++; } } } if(!ok||!topsort()){ cout<<"NO"<<endl; return 0; } cout<<"YES"<<endl; for(int i=1;i<=n;i++) cout<<ans[i]<<" "; cout<<endl; return 0; }
Educational Codeforces Round 103 (Rated for Div. 2) E Pattern Matching
标签:pop rgb enter color pac 匹配 链接 style force
原文地址:https://www.cnblogs.com/tombraider-shadow/p/14349896.html