24h購物| | PChome| 登入
2013-07-07 17:56:45| 人氣746| 回應0 | 上一篇 | 下一篇

[UVA][bfs] 1377 - Ruler

推薦 0 收藏 0 轉貼0 訂閱站台

Xiaoming wants to make a special ruler, which can directly measure several given lengths. Xiaoming hopes to find a way, making the scale on ruler as few as possible, while for a given length, there exists two scales on ruler and the distance between the two scales is equal to the given length. For scales as few as possible, we also hope the length of ruler as short as possible to save the material cost.

Input 

Input contains several cases. Each case has two lines. The first line is an integer n ( 1 $ leq$ n $ leq$ 50) to specify how many given lengths need to measure. The second line contains n integers d1, d2,...dn, indicating the length values respectively ( 1 $ leq$ di $ leq$ 106, i $ in$ [1, n]).

The last case is followed by a line containing a zero.

Output 

For each case, output three lines. The first line contains the case number. The second line is an integer M to specify the minimized number of scales needed. The third line is M integers to specify the distance between the leftmost scales and the other M scales respectively.


Note: output scales in ascending order, the first number is always 0. You can assume that M won't exceed 7.

Sample Input 

6
5 15 20 25 35 40
0

Sample Output 

Case 1:
4
0 5 25 40

中文翻譯已經在 不幸狗中替大家翻譯了。

題目解法:

盡可能最少刻度個數,而且同時要越短越少。
那麼使用 bfs 去拓展,因為刻度最大值為 7,因此也才 21 種可能,因此輸入要去重覆。
去重覆後,便可以進行 bitmask 壓縮。
但是 bfs 只能保證最少個數,使用一下優先隊列將最短的優先踢出來。
為了加快拓展的速度,也嘗試用扣的得到新的刻度。

#include <stdio.h>
#include <string.h>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
struct E {
int v[8], ss;
int matched;
bool operator<(const E &A) const {
if(ss != A.ss)
return ss > A.ss;
if(v[ss] != A.v[ss])
return v[ss] > A.v[ss];
static int i;
for(i = 0; i < 8; i++)
if(v[i] != A.v[i])
return v[i] < A.v[i];
return false;
}
};
void sol(int n, int A[]) {
E tn;
priority_queue<E, vector<E> > Q;
map<int, int> M;
map<int, int>::iterator it;
set<E> R;
int i, j, k, ss;
int final = (1<<n)-1;
memset(&tn, 0, sizeof(tn));
Q.push(tn);
R.insert(tn);
for(i = 0; i < n; i++)
M[A[i]] = i;
while(!Q.empty()) {
tn = Q.top(), Q.pop();
if(tn.matched == final) {
printf("%d\n", tn.ss+1);
for(i = 0; i <= tn.ss; i++) {
if(i) putchar(' ');
printf("%d", tn.v[i]);
}
puts("");
return;
}
for(i = 1; i < 8; i++) {
if(tn.v[i] == 0) {
ss = i;
break;
}
}
for(j = 0; j < ss; j++) {
for(i = 0; i < n; i++) {
if((tn.matched>>i)&1)
continue;
E tmp;
tmp = tn;
tmp.ss = ss;
tmp.v[ss] = tn.v[j] - A[i];
if(tmp.v[ss] > 0) {
for(k = 0; k < ss; k++) {
it = M.find(abs(tmp.v[ss]-tmp.v[k]));
if(it != M.end()) {
tmp.matched |= 1<<(it->second);
}
}
sort(tmp.v, tmp.v+ss+1);
if(R.find(tmp) == R.end()) {
R.insert(tmp);
Q.push(tmp);
}
}
}
for(i = 0; i < n; i++) {
if((tn.matched>>i)&1)
continue;
E tmp;
tmp = tn;
tmp.ss = ss;
tmp.v[ss] = tn.v[j] + A[i];
for(k = 0; k < ss; k++) {
it = M.find(abs(tmp.v[ss]-tmp.v[k]));
if(it != M.end()) {
tmp.matched |= 1<<(it->second);
}
}
sort(tmp.v, tmp.v+ss+1);
if(R.find(tmp) == R.end()) {
R.insert(tmp);
Q.push(tmp);
}
}
}
if(R.size() > 500000)
break;
}
printf("NOT FOUND");
while(1);
}
int main() {
//freopen("in.txt", "r+t", stdin);
int n, cases = 0, A[55];
int i, j;
while(scanf("%d", &n) == 1 && n) {
for(i = 0; i < n; i++)
scanf("%d", &A[i]);
printf("Case %d:\n", ++cases);
sort(A, A+n);
for(i = 1, j = 0; i < n; i++) {
if(A[i] != A[j])
A[++j] = A[i];
}
n = j+1;
sol(n, A);
}
return 0;
}
 

台長: Morris
人氣(746) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: UVA |
此分類下一篇:[UVA] 10705 - The Fun Number System
此分類上一篇:[UVA][剪枝] 10543 - Traveling Politician

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文