Description
给定一个长度为5~12个不同字符组成的字符串,从中选取5个,设为v,w,x,y,z,要满足等式:v-w^2+x^3-y^4+z^5=target,现在给出字符串和target,求满足该条件的5个字符(字典序要最大)
Input
多组用例,每组用例包括一个整数target和一个字符串s(target<=12000000),以0 END结束输入
Output
对于每组用例,若存在满足条件的5个字符则输出,若不存在则输出no solution
Sample Input
1 ABCDEFGHIJKL
11700519 ZAYEXIWOVU
3072997 SOUGHT
1234567 THEQUICKFROG
0 END
Sample Output
LKEBA
YOXUZ
GHOST
no solution
Solution
此题因数据太弱可以直接五重循环暴力水过,不过时间复杂度O(n^5)过于口怕QAQ,故也可以利用折半枚举将时间复杂度降为O(n^2)或者O(n^3),但还是感觉太慢,所以写了个dfs,因为可能有多组可行解,但题目要求输出字典序最大的那个,所以先将字符串按升序排序然后再搜索,这样得到的第一组可行解一定是字典序最大的那个,注意回溯
Code
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int target;
char s[15];
bool vis[15];
int num[5];
int cmp(char a,char b)//对字符串由大到小排序
{
return a>b;
}
int power(int x,int n)//求阶乘
{
int temp=1;
for(int i=1;i<=n;i++)
temp*=x;
return temp;
}
int dfs(int x)
{
if(x==5)//若满足条件则返回1,否则返回0
{
int sum=num[0]-power(num[1],2)+power(num[2],3)-power(num[3],4)+power(num[4],5);
if(sum==target)
return 1;
return 0;
}
for(int i=0;i<strlen(s);i++)
if(!vis[i])
{
vis[i]=1;
num[x]=s[i]-'A'+1;
if(dfs(x+1))//满足条件则返回1
return 1;
else
vis[i]=0;//回溯
}
return 0;//都不满足条件,返回0
}
int main()
{
while(scanf("%d %s",&target,s)!=EOF)
{
if(target==0&&s[0]=='E')
break;
memset(vis,false,sizeof(vis));//初始化
memset(num,0,sizeof(num));//初始化
sort(s,s+strlen(s),cmp);
if(dfs(0))
{
for(int i=0;i<5;i++)
printf("%c",num[i]+'A'-1);
printf("\n");
}
else
printf("no solution\n");
}
return 0;
}