2087: Tragedy Words
Submit Page Summary Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 144 Solved: 58
Description
As is known to all, Wells doesn't have a good command of English. As a result, some unfamiliar words, which may cause sadness of Wells, is called tragedy words. In more detail, a word will be defined as a tragedy word, if and only if when it satisfies all following conditions.
First, it only contain uppercase letter.
Second, it doesn't contain three consecutive vowel(AEIOU) or three consecutive consonant(the other 21 letter).
And last of all, it should contain at least one special tragedy letter 'L'.
Now, you are given a word, which consists of uppercase letter or underline, and you are allow to fill each underline with one uppercase letter. And in order to make fun of Wells, you want to know how many tragedy words you can make in this way.
Input
For each test, only contains a line of one word, which consists of uppercase letter and underline(’_’).
The total length of each word will not exceed 100, and the number of underline(’_’) will not exceed 10.
Output
For each test, print one line, which contains a integer as the total amount of tragedy words you can make.
Notice: the number may be very large and may exceed the 32-bits unsigned integer.
Sample Input
V__K
V_K
Sample Output
10
0
Hint
The vowel means 'A','E','I','O','U'
The consonant means the other 21 letter.
The special tragedy letter 'L' still belongs to consonant.
Of course, the letter here means English letters, not other language letters.
思路:
dfs从头进行搜索,找出符合条件的填充时的元音和辅音数量,分别令为a,b。则sum+=(21^b-20^b)*5^a
代码::
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long LL;
LL cnt;
int sign;
inline LL po(LL num,LL tim)
{
int i;
LL ans=1;
for(i=1;i<=tim;i++)
{
ans*=num;
}
return ans;
}
LL ans=0;
void get_ans(LL x,LL q)
{
if(sign==0)
ans+=(po(21,x)-po(20,x))*po(5,q);
else ans+=po(21,x)*po(5,q);
}
char str[105];
int ss[105];
set<char> s;
void init()
{
s.insert('A');
s.insert('O');
s.insert('E');
s.insert('I');
s.insert('U');
}
void pre_solve()
{
int len=strlen(str);
for(int i=0;i<len;i++)
{
if(s.count(str[i]))
{
ss[i]=1;//元音为1
}
else if(str[i]!='_')
{
ss[i]=-1;//辅音为-1
}
else{
ss[i]=0;
}
if(str[i]=='L') sign=1;
}
}
inline bool cannot(int i,int j,int k)
{
if(abs(ss[i]+ss[j]+ss[k])==3) return false;
return true;
}
inline int check(int n,int num)
{
ss[n]=num;
int len=strlen(str)-1;
bool a=true,b=true,c=true;
if(n<2)
{
if(n==1)
{
a=cannot(0,1,2);
b=cannot(1,2,3);
}
if(n==0)
{
a=cannot(0,1,2);
}
}
else if(n>len-2)
{
if(n==len-1)
{
a=cannot(len,len-1,len-2);
b=cannot(len-1,len-2,len-3);
}
if(n==len)
{
a=cannot(len,len-1,len-2);
}
}
else
{
a=cannot(n-1,n,n+1);
b=cannot(n-2,n-1,n);
c=cannot(n,n+1,n+2);
}
return a&&b&&c;
}
void dfs(int l,LL x,LL q)
{
int len=strlen(str);
if(l==len)
{
get_ans(x,q);
//cout<<x<<q<<endl;
return;
}
if(ss[l]==0)
{
if(check(l,1))
{
dfs(l+1,x,q+1);
ss[l]=0;
}
if(check(l,-1))
{
dfs(l+1,x+1,q);
ss[l]=0;
}
}
else dfs(l+1,x,q);
}
int main()
{
//LL x,q;
init();
while(cin>>str)
{
sign=0;
ans=0;
pre_solve();
dfs(0,0,0);
cout<<ans<<endl;
memset(str,0,sizeof(str));
}
return 0;
}