2 条题解

  • 1
    @ 2026-8-27 14:54:43

    为什么开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
      @ 2026-4-20 23:06:52
      // 代码由我本人编写,注释由千文 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
      上传者