poj1416

题目大意:给定一个目标数和一个写在纸上将被粉碎的数,被粉碎的意思是将整数进行分割(如12346 1+2+34+6),求分割后的数加起来小于目标数且最接近目标数,如果分割的方式不止一种,输出rejected;如果目标数和指定的数相同,直接输出;如果目标数小于分割的最小数,输出error;否则,输出最接近目标数的数,并输出分割方式。
题目分析:DFS找出最优解
poj1416
每位数一个一个的加入,用一个字符数组存放,向字符数据加入的方式分别是"+X"和"X"(X为第几个数)
在写个函数用来计算字符数组的值。

题目实现:
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
int target;               //目标数
int len;                 //搜索的深度
int visit[20];           //存放输入整数的各个位数
int ans;                 //存放差值
int result;               //存放结果
int num;                 //用来计数可能出现的相同结果的次数
char path[100];
char finalPath[100];    


int IntShredded;                 //被分割数的整数形式
char shredded[20];           //被分割的字符串

void DFS(int depth,int sum);
int addString(char *s);


int main ()
{

int i,m;
int n;
      while(cin>>target>>shredded)
{
    if(target==0 && shredded[0]=='0')
break;

          len=strlen(shredded);                 //输入字符串的长度
                       

for(i=1;i<=len;i++)                 //将输入的字符转换成为整形存储在visit[]数组中
visit[i]=shredded[i-1]-'0';
           
            IntShredded=addString(shredded);                       //将输入的数据转成为一个整数
               

    m=0;                               //将每位数都相加得出和的最小值
for(i=1;i<=len;i++)
                m+=visit[i];

        if(IntShredded==target)
{
cout<<target<<" "<<target<<endl;
continue;
}


    if(m>target)                       //目标数小于和的最小值
{
cout<<"error"<<endl;
continue;
}

        ans=99999;                           //初始化操作
  finalPath[0]='\0';                
  num=0;
        path[0]='0';                   //path第一个数添加为0,那么以后每个前面输出的时候要除去这个0
  path[1]='\0';
        DFS(1,0);

 
  int k;
  int finalPLen=strlen(finalPath);

    if(num==1)                            
    {
cout<<result<<" ";                        
 
for(k=1;k<finalPLen;k++)                   //将路径进行输出,finalPath[0]肯定是0
{
    if(finalPath[k]=='+' && k>1)                       //k>1 如("0+1+2+3+4+5+6")
cout<<" ";
 
 
if(finalPath[k]!='+')
cout<<finalPath[k];
}
cout<<endl;
    }
  else
cout<<"rejected"<<endl;

}

  return 0;
}


void DFS(int depth,int sum)
{
int pathLen=strlen(path);

if(sum>target) return;

    if(depth>len)
{
        if(target-sum<ans)
  {
      cout<<path<<endl;
  strcpy(finalPath,path);     //将路径保存
  num=0; 
  result=sum;
  ans=target-sum;
    cout<<"***"<<ans<<endl;
return ;
  }
  if(target-sum==ans)
          num++;
 
  return ;
}

path[pathLen]='+';
path[pathLen+1]=shredded[depth-1];
path[pathLen+2]='\0';
int m=addString(path);

  DFS(depth+1,m);
     
    path[pathLen]=shredded[depth-1];
path[pathLen+1]='\0';
m=addString(path);
   
DFS(depth+1,m);

}



int addString(char *s)       //对一个字符串进行求和
{
  int n,temp=0;
  int i,j;
  int sum=0;
  n=strlen(s);
   

  for(i=0;i<n;i++)
  {

    if(s[i]=='+')
{
  sum=sum+temp;
  temp=0;
}

else
{
j=s[i]-'0';
  temp=10*temp+j;
}

   
  }
   


  return sum+temp;
}











  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值