题意
给出一些数字,要求输出一些标记,根据这些标记可以得到上面的所有数字。
思路
一开始写了个贪心,后来发现不行。又写了个DFS,TLE了。最后还是看了帆神和柯神的题解。
这里好像有个YY的结论:最后所选的标号要么是给出的,要么是他们之间的差。
用BFS。不过好像所用的最长长度不能超过输入的最长,题目没说。感觉不太科学。
然后就是每走一步就加上每一个还没选到的值的和和差。我用了set判重。
代码
#include <cstdio>
#include <stack>
#include <set>
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <functional>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <ctime>
#include <string>
#include <map>
#include <iomanip>
#include <cmath>
#define LL long long
#define ULL unsigned long long
#define SZ(x) (int)x.size()
#define Lowbit(x) ((x) & (-x))
#define MP(a, b) make_pair(a, b)
#define MS(arr, num) memset(arr, num, sizeof(arr))
#define PB push_back
#define F first
#define S second
#define ROP freopen("input.txt", "r", stdin);
#define MID(a, b) (a + ((b - a) >> 1))
#define LC rt << 1, l, mid
#define RC rt << 1|1, mid + 1, r
#define LRT rt << 1
#define RRT rt << 1|1
#define BitCount(x) __builtin_popcount(x)
#define BitCountll(x) __builtin_popcountll(x)
#define LeftPos(x) 32 - __builtin_clz(x) - 1
#define LeftPosll(x) 64 - __builtin_clzll(x) - 1
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
using namespace std;
const double eps = 1e-6;
const int MAXN = 50 + 10;
const int MOD = 1000007;
typedef pair<int, int> pii;
typedef vector<int>::iterator viti;
typedef vector<pii>::iterator vitii;
struct STATE
{
int ans;
set<int> st;
}ans;
map<int, int> mp;
vector<int> num;
set<int> iniNum, vis;
int n;
void Init()
{
mp.clear(); num.clear(); iniNum.clear(); vis.clear();
for (int i = 0; i < n; i++)
{
int tmp;
scanf("%d", &tmp);
if (!iniNum.count(tmp))
{
num.push_back(tmp);
iniNum.insert(tmp);
}
}
sort(num.begin(), num.end());
for (int i = 0; i < SZ(num); i++) mp[num[i]] = i;
ans.ans = 0, ans.st.clear();
}
STATE Add(int num, STATE cur)
{
for (set<int>::iterator it = cur.st.begin(); it != cur.st.end(); it++)
{
int tmp = abs(*it - num);
if (mp.count(tmp)) cur.ans |= (1 << mp[tmp]);
}
cur.st.insert(num);
return cur;
}
void BFS()
{
STATE cur;
queue<STATE> qu;
cur.ans = 0, cur.st.insert(0);
qu.push(cur);
int result = (1 << SZ(num)) - 1;
while (!qu.empty())
{
cur = qu.front(); qu.pop();
if (cur.ans == result)
{
if (SZ(ans.st) == 0) ans = cur;
else
{
if (SZ(cur.st) > SZ(ans.st)) return;
else if (SZ(ans.st) > SZ(cur.st)) ans = cur;
else if (*ans.st.rbegin() > *cur.st.rbegin()) ans = cur;
}
}
else
{
if (SZ(cur.st) > 7) continue;
for (int i = 0; i < SZ(num); i++)
{
if (((1 << i) & cur.ans) == 0)
{
for (set<int>::iterator it = cur.st.begin(); it != cur.st.end(); it++)
{
if (*it + num[i] <= *(--num.end()))
{
STATE tmp = Add(*it + num[i], cur);
if (!vis.count(tmp.ans)) qu.push(tmp);
vis.insert(tmp.ans);
}
if (*it > num[i])
{
STATE tmp = Add(*it - num[i], cur);
if (!vis.count(tmp.ans)) qu.push(tmp);
vis.insert(tmp.ans);
}
}
}
}
}
}
}
int main()
{
//ROP;
int i, j, cases = 0;
while (scanf("%d", &n), n)
{
Init();
BFS();
printf("Case %d:\n", ++cases);
printf("%d\n", SZ(ans.st));
set<int>::iterator it = ans.st.begin();
for (; it != ans.st.end(); it++)
{
if (it == ans.st.begin()) printf("%d", *it);
else printf(" %d", *it);
}
puts("");
}
return 0;
}