题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1015
#include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #define res(v,w,x,y,z) v-w*w+x*x*x-y*y*y*y+z*z*z*z*z using namespace std; /**************************************************************************************************************** 题意: 输入一个数target 和一个字符串 s,在字符串 s 找出一个由5个字符组成的最大字符串 使得v - w^2 + x^3 - y^4 + z^5 = target ; 思路: 一: 暴力求解,五个for循环,经验证不超时 2333。但是我TM是来练搜索的,恩对!搜索!!! 二: 1,刚开始我想复杂了,想着每次 dfs 可以把当前的 sum 更新并作为参数传进去, 但是一直不对。 2,看了网上的思路,每次 dfs到头 return true的时候,将当前数字保存,最后判断即可 3,讲道理,赋值语句也就是保存,不需要时间。时间复杂度 O(0); 4,慢慢的已经可以理解 搜索+回溯 的原理了,在搜索的基础上将图案重新涂白就是回溯 ****************************************************************************************************************/ int visit[26+5]; int N[26+5],f[5]; string s; long target; bool dfs(int num) //一般的搜索直接定义 void 类型返回空值即可,但是搜索+回溯要判断是否可以达到目的的 //必须用 true 和 false 进行判断,所以定义 bool 类型 { if(num == 5){ if(res(f[0],f[1],f[2],f[3],f[4]) == target) //最后判断即可。dfs到根,判断是否达到目的 return true; else return false; } for(int i = s.size()-1 ;i >= 0;i --){ if(visit[i]) continue; visit[i]=1; f[num]=N[i]; //每次保存当前数值,最后不可以达到目的就不输出。 if(dfs(num+1)) return true; visit[i]=0; //if语句不成立,也就是说 dfs 到头并不能达到目的,那么就回溯,重新涂白图案。 } return false; } int main() { while(cin>>target>>s) { if(target == 0 && s == "END") break; memset(visit,0,sizeof(visit)); for(int i = 0;i < s.size();i ++) N[i] = (int)s[i] - 64; sort(N,N+s.size()); if(dfs(0)){ for(int i = 0;i < 5;i ++) printf("%c",f[i]+'A'-1); //不懂得点,不知道怎么用C++输出字符,强制类型转换也不可以 cout<<endl; } else cout<<"no solution"<<endl; } return 0; }