NC20427. [SHOI2013]阶乘字符串
描述
输入描述
输入第1行一个整数T,表示这个文件中会有T组数据。
接下来分T个块,每块2行:
第1行一个正整数n,表示S由前n个小写字母组成。
第2行一个字符串S。
输出描述
对于每组数据,分别输出一行。每行是YES或者NO,表示该数据对应的串S是否是阶乘字符串。
示例1
输入:
2 2 bbaa 2 aba
输出:
NO YES
说明:
【样例解释】C++(g++ 7.5.0) 解法, 执行用时: 390ms, 内存消耗: 8700K, 提交时间: 2023-06-04 12:54:15
#include <iostream> #include <cstdio> #include <cstring> #include <string> using namespace std; int T,n,mxb; int f[2097152],g[460][26]; string s; int main() { for (scanf("%d",&T);T;T--) { scanf("%d",&n); cin>>s; mxb=1<<n; int len=s.length(); if (n>21) { printf("NO\n"); continue; } for (int i=0;i<n;i++) g[len][i]=g[len+1][i]=len+1; for (int i=len;i;i--) { for (int j=0;j<n;j++) g[i-1][j]=g[i][j]; g[i-1][s[i-1]-'a']=i; } memset(f,0,sizeof f); for (int i=1;i<mxb;i++) for (int j=0;j<n;j++) if (i&(1<<j)) f[i]=max(f[i],g[f[i^(1<<j)]][j]); if (f[mxb-1]<=len) printf("YES\n"); else printf("NO\n"); } }
C++(clang++ 11.0.1) 解法, 执行用时: 576ms, 内存消耗: 16908K, 提交时间: 2023-04-25 15:45:17
#include<bits/stdc++.h> #define MAXN 505 using namespace std; int t,n,m;char s[MAXN]; int f[MAXN][30]; int g[1<<22]; int main(){ scanf("%d",&t); while(t--){ scanf("%d%s",&n,s+1); m=strlen(s+1); if(n>21){ puts("NO"); continue; } memset(f,-1,sizeof f); for(int i=1;i<=m;++i){ for(int j=0;j<n;++j) f[i][j]=f[i-1][j]; f[i][s[i]-'a']=i; } for(int i=0;i<(1<<22);++i) g[i]=m; for(int s=1;s<(1<<n);++s) for(int i=0;i<n;++i){ if(g[s^(1<<i)]==-1){ g[s]=-1; continue; } if(s&(1<<i)) g[s]=min(g[s],f[g[s^(1<<i)]][i]); } puts(g[(1<<n)-1]<0?"NO":"YES"); } return 0; }