ACM解题报告-HD1015
链接地址:http://acm.hdu.edu.cn/showproblem.php?pid=1015
hd1015题,据说用5个for循环暴力也行,这里我用了深度优先搜索(dfs),主要想练习一下深搜,可能未来的一段时间内都会刷深搜的题目。废话不说,来看看题目。
这道题的大体意思就是给你一个target值和一串字符串(大写字母),各字母在字母表中的顺序可以代表其值,例如A的值就是1,B的值是2,Z的值是26.....然后给出一个方程式:v - w^2 + x^3 - y^4 + z^5 = target,其中的v,w,x,y,z分别用给出的各字母的值来替换,最后输出满足方程式的字母顺序,当然可能出现多个满足方程的字母序列,如果出现这种情况,那么最后输出字母表中最靠后的字母开头的序列。主体思路就是进行dfs,把它们全都遍历一遍,选出满足方程的序列,要注意的一点就是当出现多个序列时,如何才能选择字母较靠后的字母开头的序列表,我这里做的处理就是先进行降序排列,搜索时从大到小进行搜索,最后得到的序列就能符合题意了。
代码如下:(用了G++编译)
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<iostream> using namespace std; int cmp( const void *a,const void *b) { return *(int *)a<*(int *)b?1:-1;//降序排列 } int target,k,len,w; int b[26],c[26],mark[26],t[26]; char a[27]; void dfs(int k) { int i,j; if(k==5&&w==0) { if(( t[0]-t[1]*t[1]+t[2]*t[2]*t[2]-t[3]*t[3]*t[3]*t[3]+t[4]*t[4]*t[4]*t[4]*t[4])==target)//找出符合方程式的序列并记录在c[ ]中 { w=1; for(j=0;j<5;j++) c[j]=t[j]; } } else if(k<5) { for(i=0;i<len;i++) { if(!mark[i]) { mark[i]=1;//标志走过的点 t[k]=b[i]; dfs(k+1); mark[i]=0;//退回不符合条件的点 } } } } int main( ) { while(scanf("%d%s",&target,a)!=EOF) { int i; len=strlen(a); k=0; w=0; memset(mark,0,sizeof(mark)); if(target==0&&strcmp(a,"END")==0) break; for(i=0;i<len;i++) b[i]=a[i]-64;//利用了字母的ASCII值 qsort(b,len,sizeof(b[0]),cmp);//将数组b进行降序排列 dfs(k); if(w==0) cout<<"no solution"<<endl; else { for(i=0;i<5;i++) { printf("%c",c[i]+64); } cout<<endl; } } return 0; }