题目大意:输入一个字符串和一个整数target,其中字符串中A-Z分别对应的数字1-26,从中任取长度为5的子字符串ABCDE(假设对应的数字是abcde),使其满足target=a-b^2+c^3-d^4+e^5,输出这些子字符串中字典序最大的一个
思路:一个枚举排列问题。。。dfs回溯枚举每个子串,用一个数组B记录每次枚举符合要求的子串对应的数字,再用另一个数组C保存枚举过的子串中字典序最大的一个对应的数字序列,若存在输出C,否则no solution
#include<stdio.h>
#include<string.h>
#include<math.h>
char s[30];
int A[30],n,target,B[6],C[6]; //A用来记录字符是否使用过,B记录每次遍历的5个字符对应的数字,C记录字典序最大的5个字符对应的数字
void dfs(int m){
int i,k=0,x=0;
if(m<=5){ //m(字符串长度)小于等于5时,dfs回溯
for(i=0;i<n;i++){
if(A[i]){
A[i]=0;
B[m]=s[i]-'A'+1;
dfs(m+1);
A[i]=1;
}
}
}
else{ //m大于5时,k记录B串按题目公式计算得到的大小,k再和target比较
for(i=1;i<=5;i++){
if(i%2==0) k-=pow(B[i],i);
else k+=pow(B[i],i);
}
if(k==target){
for(i=1;i<=5;i++){ //比较当前枚举到的子串B与目前的字典序最大的子串C,若B大,则更新C
if(B[i]==C[i]) continue;
if(B[i]<C[i]) break;
if(B[i]>C[i]) x=1;
}
if(x) for(i=1;i<=5;i++) C[i]=B[i];
return;
}
}
}
int main(){
while(scanf("%d%s",&target,&s)){
if(strcmp(s,"END")==0&&target==0) break;
n=strlen(s);
memset(C,0,sizeof(C));
memset(B,0,sizeof(B));
for(int i=0;i<n;i++) A[i]=1;
dfs(1);
if(C[1]){ //C不为0即情况存在
for(int i=1;i<=5;i++)
printf("%c",C[i]-1+'A');
}
else printf("no solution");
printf("\n");
}
return 0;
}