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;
}

 

posted @ 2013-05-13 19:58  paradise in hell  Views(175)  Comments(0Edit  收藏  举报