POJ 1248 && HDU 1015 Safecracker(dfs)

来源:互联网 发布:小学语文软件天天练 编辑:程序博客网 时间:2024/05/19 21:02

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;}
0 0
原创粉丝点击