Newcoder 156 D. 托米的咒語(next_permutation)
阿新 • • 發佈:2018-12-12
Description
托米沒有完成上一個任務,準備施展黑魔法推倒
黑魔法咒語被描述為一個長為的,僅包含小寫英文字母的字串,在托米所在的星球,魔法造成的每次有效傷害都是來自他的一個子序列,對於每一個的排列(共 種),若作為咒語的子序列出現, 就會造成的傷害
而咒語的總傷害為所有 的排列造成的傷害值之和,托米能打出多少點的傷害,是否能擊敗$ 1317$ 呢?
Input
一行輸入一個字串
Output
一行輸出一個數,表示傷害值
Sample Input
aabcdefghi
Sample Output
1
Solution
列舉這九個字母的全部排列,之後判斷排列是否在該字串內即可,預處理每個字元在字串中出現的第一個位置以及第個位置後第個字元出現的位置即可判斷所列舉的排列是否在字串中
Code
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define maxn 3005 char s[30],a[maxn]; int First[10],Next[maxn][10],pos[10]; int main() { scanf("%s",a+1); int len=strlen(a+1); for(int i=1;i<=len;i++) if(First[a[i]-'a']==0)First[a[i]-'a']=i; memset(pos,0,sizeof(pos)); for(int i=len;i>=1;i--) { for(int j=0;j<9;j++)Next[i][j]=pos[j]; pos[a[i]-'a']=i; } for(int i=0;i<9;i++)s[i]='a'+i; int ans=0; do { int pos=First[s[0]-'a']; for(int i=0;i<8;i++) { if(Next[pos][s[i+1]-'a']==0) { pos=0; break; } pos=Next[pos][s[i+1]-'a']; } if(pos)ans++; }while(next_permutation(s,s+9)); printf("%d\n",ans); return 0; }