HDU 1258 Sum It Up
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1258
一道以前做过的搜索题.解法就是排序后搜索.
题目要求相同的解只输出一次.
记得以前看过别人的解法是搜索时加个限定条件,一时没想起来,所以自己乱搞.
所谓乱搞就是用哈希了,用累加的序列构造哈希表.嘛,虽然做起来我也觉得有点运气成分.(因为构造哈希的算法是乱来的)
没有验证过的哈希算法经不起推敲,也许数据强点我就挂了..还是贴代码吧,这次写丑了,懒得改.
#include <iostream> #include <algorithm> using namespace std; int num[12]; int vis[12]; int hash[1000]; int sum,n,pre_t = 1; int isNone = 1; void DFS(int pos,int temp) { if(temp == sum) { int t = 1; for(int i=0;i<n;i++) { if(vis[i] != -1) { if(num[i] < 11) t = (t * num[i] + 11) % 1000 ; else if( num[i] < 33) t = (t * num[i] * num[i] + 11) % 1000; else if( num[i] < 71) t = (t * num[i] * t + 111) % 1000; } } if(!hash[t]) { bool isStart = 1; for(int i=0;i<n;i++) { if(vis[i]!=-1) { if(isStart) { cout<<num[i]; isStart = 0; isNone = 0; } else cout<<"+"<<num[i]; } } cout<<endl; hash[t] = 1; } return; } if(pos>=n) return; for(int i=pos;i<n;i++) if(temp + num[i]<= sum) { vis[i] = 1; DFS(i+1,temp+num[i]); vis[i] = -1; } } bool cmp(int a,int b) { return a>b; //升序排列,如果改为return a>b,则为降序 } int main(int argc, const char *argv[]) { freopen("input.txt","r",stdin); while(cin>>sum>>n&&(sum+n)) { memset(vis,-1,sizeof(vis)); memset(hash,0,sizeof(hash)); for(int i=0;i<n;i++) cin>>num[i]; sort(num,num+n,cmp); printf("Sums of %d:\n",sum); DFS(0,0); if(isNone) { printf("NONE\n"); } isNone = 1; } return 0; }
另附上别人的参考程序,此为正解.
#include <iostream> #include <algorithm> using namespace std; bool vis[100],flag; int a[100],n,m,top; int ans[100]; void print(int top) { cout<<ans[0]; for(int i=1;i<top;i++) cout<<"+"<<ans[i]; cout<<endl; } void BFS(int sum,int pos) { for(int i=pos;i<m;i++) { int now=sum+a[i]; if(now<n) { vis[i]=true; ans[top++]=a[i]; BFS(now,i+1); vis[i]=false; --top; } else if(now==n) { ans[top++]=a[i]; print(top); --top; flag=1; } while(a[i]==a[i+1]) ++i;//此处亮点,使接下来不再出现以相同的a[i]为第top个数的序列,避免了重复. } } bool cmp(const int &a,const int &b) { return a>b; } int main() { // freopen("test.txt","r",stdin); int i; while(cin>>n>>m,n) { flag=0; int sum=0; for(i=0;i<m;i++) { cin>>a[i]; sum+=a[i]; } cout<<"Sums of "<<n<<":"<<endl; if(sum<n) { cout<<"NONE"<<endl;continue;} sort(a,a+m,cmp); BFS(0,0); if(!flag) cout<<"NONE"<<endl; } return 0; }