HDU - 1015 Safecracker
题目链接: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;
}
浙公网安备 33010602011771号