当前位置: 代码迷 >> 综合 >> 【BZOJ1055】【HAOI2008】玩具取名
  详细解决方案

【BZOJ1055】【HAOI2008】玩具取名

热度:38   发布时间:2024-01-13 09:55:35.0

题目链接:传送门
题解:
用f[l][r][i]表示从l到r能否合成第i种字符,转移很好写

//by sdfzchy
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int inf=(1<<30),N=100010,mod=1e9+7;
int n,cnt[5];
inline int in()
{char tmp=getchar();int res=0,f=1;while((tmp<'0'||tmp>'9')&&tmp!='-')tmp=getchar();if(tmp=='-') f=-1,tmp=getchar();while(tmp>='0'&&tmp<='9')   res=(res<<1)+(res<<3)+(tmp^48),tmp=getchar();return res*f;
}
bool f[210][210][5];
bool ha[5][5][5];
int id(char c)
{if(c=='W') return 1;if(c=='I') return 2;if(c=='N') return 3;if(c=='G') return 4;
}
void put(int i)
{if(i==1) putchar('W');if(i==2) putchar('I');if(i==3) putchar('N');if(i==4) putchar('G');
}
char s[1010];
int main()
{char ss[100];for(int i=1;i<=4;i++) cnt[i]=in();for(int i=1;i<=4;i++)for(int j=1;j<=cnt[i];j++){scanf("%s",ss);ha[id(ss[0])][id(ss[1])][i]=1;}scanf("%s",s+1);n=strlen(s+1);for(int i=1;i<=n;i++) f[i][i][id(s[i])]=1;for(int i=1;i<n;i++)for(int l=1,r=i+l;l<=n-i;l++,r++)for(int j=1;j<=4;j++)if(!f[l][r][j]) for(int x=1;x<=4;x++)for(int y=1;y<=4;y++)   if(ha[x][y][j])for(int k=l;k<r;k++)f[l][r][j]|=(f[l][k][x]&f[k+1][r][y]);  bool ok=0;for(int i=1;i<=4;i++)if(f[1][n][i])put(i),ok=1;if(!ok) puts("The name is wrong!");return 0;
}