2 条题解
-
1
为什么开map还比别人快🤔
#include<bits/stdc++.h> using namespace std; const int N=2e2+10; map<char,int>mp; map<int,char>mp1; vector<pair<int,int> >G[N]; int siz[5],dp[5][N][N],a[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); mp['W']=1; mp['I']=2; mp['N']=3; mp['G']=4; mp1[1]='W'; mp1[2]='I'; mp1[3]='N'; mp1[4]='G'; for(int i=1;i<=4;i++) { cin>>siz[i]; } for(int i=1;i<=4;i++) { for(int j=1;j<=siz[i];j++) { string s; cin>>s; int x=mp[s[0]],y=mp[s[1]]; G[i].push_back({x,y}); } } string s; cin>>s; int n=s.length(); for(int i=1;i<=n;i++) { a[i]=mp[s[i-1]]; dp[a[i]][i][i]=1; } for(int k=2;k<=n;k++) { for(int t=1;t<=4;t++) { for(int l=1;l<=n-k+1;l++) { int r=l+k-1; bool flag=0; for(int q=l;q<r;q++) { if(flag) { break; } for(auto i:G[t]) { int x=i.first,y=i.second; if(dp[x][l][q]&&dp[y][q+1][r]) { dp[t][l][r]=1; flag=1; break; } } } } } } bool flag=0; for(int i=1;i<=4;i++) { if(dp[i][1][n]) { cout<<mp1[i]; flag=1; } } if(!flag) { cout<<"The name is wrong!"; } return 0; } -
0
// 代码由我本人编写,注释由千文 AI 生成 #include <bits/stdc++.h> using namespace std; const int N = 210; char s[N]; // 输入的玩具名字 int cnt[5]; // cnt[c]:字母 c 有多少条替换规则(c = 1 ~ 4) int rule[5][20][2]; // rule[c][i][0/1]:字母 c 的第 i 条变换规则的两个子字母(1 ~ 4) int id[256]; // 字符到编号映射:'W' -> 1, 'I' -> 2, 'N' -> 3, 'G' -> 4 bool dp[N][N][5]; // dp[l][r][c]:区间 [l, r] 能否由字母 c 推导出 int main() { ios::sync_with_stdio(false); cin.tie(0); // 初始化字母映射 id['W'] = 1; id['I'] = 2; id['N'] = 3; id['G'] = 4; // 读入每种字母的变换规则数量 for (int c = 1; c <= 4; c ++) { cin >> cnt[c]; } // 读入替换规则 char str[5]; for (int c = 1; c <= 4; c ++) { for (int i = 1; i <= cnt[c]; i ++) { cin >> str; rule[c][i][0] = id[str[0]]; rule[c][i][1] = id[str[1]]; } } // 读入目标字符串 cin >> (s + 1); int n = strlen(s + 1); // 初始化:单个字符只能由自己生成 for (int i = 1; i <= n; i ++) { dp[i][i][id[s[i]]] = true; } // 区间 DP:枚举长度 len(从 2 开始!) for (int len = 2; len <= n; len ++) { // len = 1 已初始化,从 2 开始 for (int l = 1; l + len - 1 <= n; l ++) { int r = l + len - 1; // 枚举分割点 m,将 [l, r] 拆成 [l,m] 和 [m + 1,r] for (int m = l; m < r; m ++) { // 枚举左半部分能生成的字母 a for (int a = 1; a <= 4; a ++) if (dp[l][m][a]) { // 枚举右半部分能生成的字母 b for (int b = 1; b <= 4; b ++) if (dp[m + 1][r][b]) { // 枚举哪个字母 c 能一步生成 a + b for (int c = 1; c <= 4; c ++) { // 枚举 c 的每个变换规则 for (int i = 1; i <= cnt[c]; i ++) { if (rule[c][i][0] == a && rule[c][i][1] == b) { dp[l][r][c] = 1; // 都满足直接为 1 } } } } } } } } // 按 W I N G 顺序输出可能的初始字母 string ans = ""; if (dp[1][n][1]) { ans += 'W'; } if (dp[1][n][2]) { ans += 'I'; } if (dp[1][n][3]) { ans += 'N'; } if (dp[1][n][4]) { ans += 'G'; } if (ans.empty()) { cout << "The name is wrong!"; } else { cout << ans; } cout << "\n"; return 0; }
- 1
信息
- ID
- 2708
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 8
- 标签
- 递交数
- 157
- 已通过
- 27
- 上传者