hdu 1258&&...... Sum It Up 搜索

这个题又是传说中一个代码6题的那种题.
在vjudge上可以看到6道一毛一样的题.

题面

给两个数t,n和n(不超过12)个正整数,求出所有不同子集,使得它们加起来等于t,输出这些子集.
没有答案puts一个字符串"NONE".

题解

对没错,搜索.

#pragma GCC optimize("Ofast",3)
#include<bits/stdc++.h> Ithea Myse Valgulious //在头文件这一行后面可以不加符号打其它东西,我打了个艾瑟雅上去
namespace chtholly{//fast input and output
#define ll long long
#define p32 putchar(' ') //空格
#define pl puts("") //回车
const double ten[]={1,1e1,1e2,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13,1e14,1e15,1e16,1e17,1e18,1e19};
int read(){int x=0;char c=getchar();for (;!isdigit(c);c=getchar());for (;isdigit(c);c=getchar()) x=x*10+c-'0';return x;}
int write(int x){if (!x) return putchar('0');int bit[20],i,p=0;for (;x;x/=10) bit[++p]=x%10;for (i=p;i;--i) putchar(bit[i]+48);}
int read(double &r){double x=0,t=0;int s=0,f=1;char c=getchar();for (;!isdigit(c);c=getchar()){if (c=='-') f=-1;if (c=='.') goto readt;}for (;isdigit(c)&&c!='.';c=getchar()) x=x*10+c-'0';readt:for (;c=='.';c=getchar());for (;isdigit(c);c=getchar()) t=t*10+c-'0',++s;r=(x+t/ten[s])*f;}
int read(ll &x){x=0;char c=getchar();for (;!isdigit(c);c=getchar());for (;isdigit(c);c=getchar()) x=x*10+c-'0';}
int dwrite(ll x){if (x==0) return putchar(48);int bit[20],p=0,i;for (;x;x/=10) bit[++p]=x%10;for (i=p;i>0;--i) putchar(bit[i]+48);}
int write(double x,int k=6){static int n=ten[k];if (x==0) {putchar('0'),putchar('.');for (int i=1;i<=k;++i) putchar('0');return 0;}if (x<0) putchar('-'),x=-x;ll y=(ll)(x*n)%n;x=(ll)x;dwrite(x),putchar('.');int bit[20],p=0,i;for (;p<k;y/=10) bit[++p]=y%10;for (i=p;i>0;--i) putchar(bit[i]+48);}
#undef ll
};
using namespace chtholly;
using namespace std;
int t,n,a[15],nico,ans[15];
//目前搜索到所有数字的和,目前搜索到第几个数字,枚举的子集有多少个数字
int dfs(int sum,int k,int p)//没有返回值!当void用!
{
int i;
if (sum==t) //如果扫到
  {
  nico=1;//标记一下有解
  for (i=1;i<p-1;++i) write(ans[i]),putchar('+');//输出前面的数和一个+
  return write(ans[p-1]),pl;//输出最后一个数并换行,return并不需要返回值,只要停止搜索就可以了.
  }
if (sum>t) return 0;//都大于tot还搜什么搜,走人
for (i=k+1;i<=n;++i)
  { 
  ans[p]=a[i];//子集的第p个数等于a[i]
  dfs(sum+a[i],i,p+1);//这些数的和加上a[i],从第i个数开始枚举,去找子集中的下一个数
  for (;a[i]==a[i+1];++i);//关键!!!!!重要的事情一定要说三遍!避免重复枚举!
  }
}

int main()
{
for (int i;t=read(),n=read();)
  {
  for (i=1;i<=n;++i) a[i]=read();
  printf("Sums of "),write(t),puts(":");
  nico=0,dfs(0,0,1),!nico?puts("NONE"):0;
  }
}

好了就到这里.谢谢大家的观看.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值