bfs搜索,学习http://www.cnblogs.com/woaishizhan/archive/2012/12/19/2825398.html的代码后自己写了一遍
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#include <queue>
using namespace std;
#define MAX_SIZE 1000010
//#define LOCAL
struct Node
{
set<int> st; //存储当前可表示的刻度
int found; //选取了哪些需要表示的刻度,二进制从小到大表示
};
char idx[MAX_SIZE]; //需要表示那些具体刻度idx[v]即刻度v是否是需要的刻度
set<int> ans;
int N;
int arr[100];
int MAX;//最大刻度
int staus; //满足要求刻度状态
void bfs()
{
Node temp;temp.found=0;temp.st.insert(0);
queue<Node> q;
q.push(temp);
while(!q.empty())
{
Node cur = q.front();q.pop();
if(cur.found==staus)
{
if(cur.st.size()<ans.size())
ans = cur.st;
else if( *cur.st.rbegin() < *ans.rbegin())
ans = cur.st;
return;
}
for(set<int>::iterator iter=cur.st.begin(); iter!=cur.st.end(); iter++) //遍历可表示刻度
{
Node next;int i;
for(i=0; i<N; i++)
{
//如果已被选取
if(cur.found&(1<<i)) continue; //刻度已选取
int v = *iter+arr[i];
if(cur.st.find(v)!=cur.st.end()) continue;//刻度已可表示
if(v>MAX) continue;//超过最大刻度,不需要
next=cur;
next.st.insert(v);
//添加新增此刻度后可表示的新刻度
for(set<int>::iterator iter2=cur.st.begin();iter2!=cur.st.end(); iter2++)
{
int x=abs(v-*iter2);
if(idx[x]!=-1)
{
next.found|=(1<<idx[x]);
}
}
if(next.found!=cur.found)
q.push(next);
}
for(i=0; i<N; i++)
{
//如果已被选取
if(cur.found&(1<<i)) continue; //刻度已选取
int v = *iter-arr[i];
if(cur.st.find(v)!=cur.st.end()) continue;//刻度已可表示
if(v>MAX) continue;//超过最大刻度,不需要
if(v<0) continue;
next=cur;
next.st.insert(v);
//添加新增此刻度后可表示的新刻度
for(set<int>::iterator iter2=cur.st.begin();iter2!=cur.st.end(); iter2++)
{
int x=abs(v-*iter2);
if(idx[x]!=-1)
{
next.found|=(1<<idx[x]);
}
}
if(next.found!=cur.found)
q.push(next);
}
}
}
}
int main()
{
int i,cnt=1;
#ifdef LOCAL
freopen("c:\\1.txt","r",stdin);
#endif
while(scanf("%d",&N)==1)
{
if(N==0) break;
memset(idx,-1,sizeof(idx));
ans.clear();
for(i=0; i<N; i++)
{
scanf("%d",&arr[i]);
ans.insert(arr[i]);
}
sort(arr,arr+N);
N = unique(arr,arr+N) - arr;
MAX=arr[N-1];
for(int i=0; i<N; i++)
idx[arr[i]] = i;
staus = (1<<N)-1;
bfs();
printf("Case %d:\n%d\n",cnt++,ans.size());
for(set<int>::iterator iter=ans.begin(); iter!=ans.end(); ++iter)
printf("%d ",*iter);
printf("\n");
}
return 0;
}