Uvalive 4380
题意是给出一段密文,要求找出找一种解密方式,使得解密后的文本,任意一个单词都是元辅音间隔形成的。
数据输入比较恶心,单词之间可以是空格间隔,也可以是换行符间隔,因此必须读到一个空的行才表示一个TestCase结束。
输入的文本,处理出所有单词相邻字母的情况,存储在一个26*26的二维数组中,G[u][v]表示’A’+u与’A’+v在密文中相邻。
五重循环,枚举原文中的五种元音:AEIOU,分别对应密文中的哪几个字母,那么剩下的辅音字母就对应密文中未被映射的字母。
根据枚举出来的映射判断原文中是否存在元音相邻,或者辅音相邻的情况,存在则继续枚举,不存在则有解,根据映射输出原文即可。
TestCase之间要输出一个空行。
#include<map>
#include<queue>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#define LL long long
#define LLU long long usigned
#define ls (root<<1)
#define rs (root<<1|1)
#define LSON ls,l,mid
#define RSON rs,mid+1,r
#define mm(a,b) memset(a,b,sizeof(a))
#define cl(a) memset(a,0,sizeof(a))
#define mm0x3f(a) memset(a,0x3f,sizeof(a))
#define mm_1(a) memset(a,-1,sizeof(a))
#define debug puts("It's o k here")
#define mp make_pair
#define rep(a,b,c) for(int a=(b);a<(c);a++)
using namespace std;
const int Inf=0x3f3f3f3f;
const int maxn=1e6+5;
const int maxnode=1e5+5;
const int sigma_size=26;
const int maxs=105;//pattern string numbers
const int maxt=1e3+5;
int n, m;
char s[maxn];
int G[sigma_size][sigma_size];
int vow[sigma_size], oth[sigma_size];
int vow_cnt, oth_cnt;
int is_vowel[26];
int v[5], v2[26];
vector<string> sset;
void output(){
// for(int i=0;i<5;i++)
// printf("%c ",v[i]+'A');
// for(int i=0;i<26;i++)
// if(!is_vowel[i]) printf("%c->%c\n", 'A'+i, v2[i]+'A');
// puts("");
for(int si=0;si<sset.size();si++){
n=sset[si].length();
for(int i=0;i<n;i++)
if(sset[si][i]!=' '){
int j=sset[si][i]-'A';
if(j==v[0]) printf("A");
else if(j==v[1]) printf("E");
else if(j==v[2]) printf("I");
else if(j==v[3]) printf("O");
else if(j==v[4]) printf("U");
else printf("%c",v2[j]+'A');
}
else printf(" ");
puts("");
}
}
void solve(){
int no_ans=0;
for(v[0]=0;v[0]<26;v[0]++)
for(v[1]=v[0]+1;v[1]<26;v[1]++)
for(v[2]=v[1]+1;v[2]<26;v[2]++)
for(v[3]=v[2]+1;v[3]<26;v[3]++)
for(v[4]=v[3]+1;v[4]<26;v[4]++){//map vowels in source text to character in encoded text
no_ans=0; cl(is_vowel);
for(int i=0;i<5;i++) is_vowel[v[i]]=1;
for(int i=0;i<5&&!no_ans;i++)
for(int j=0;j<5&&!no_ans;j++)
if(G[v[i]][v[j]]) no_ans=1;
if(no_ans){
continue;
}
for(int i=0;i<26&&!no_ans;i++)
for(int j=0;j<26&&!no_ans;j++)
if(!is_vowel[i]&&!is_vowel[j]&&G[i][j]) no_ans=1;
if(no_ans){
continue;
}
for(int i=0, j=0;i<26;i++)
if(!is_vowel[i]){
v2[i]=oth[j++];
}
output();
return;
}
puts("impossible");
}
int main(){
int T, cas=0;
bool flag;
for(int i=0;i<26;i++)
if('A'+i!='A'&&'A'+i!='E'&&'A'+i!='I'&&'A'+i!='O'&&'A'+i!='U'){
oth[oth_cnt++]=i;
}
while(gets(s)){
sset.clear();
if(cas++!=0) printf("\n");
cl(G); cl(is_vowel);
do{
n=strlen(s);
for(int i=1;i<n;i++)
if(s[i-1]!=' '&&s[i]!=' '){
int u=s[i-1]-'A';
int v=s[i]-'A';
G[u][v]=1; G[v][u]=1;
}
sset.push_back(string(s));
}while((flag=gets(s))&&s[0]);
solve();
if(!flag) break;
}
return 0;
}