UVa 12844 - Outwitting the Weighing Machine

contents

  1. 1. Problem
  2. 2. Sample Input
  3. 3. Sample Output
  4. 4. Solution

Problem

有五個人要測體重,倆倆上去秤得到體重總和為何,現在反推每個人的體重為多少。

Sample Input

1
2
3
4
3
114 116 118 120 121 122 123 124 125 129
110 111 114 115 118 118 119 122 123 126
180 190 190 196 196 206 216 216 226 232

Sample Output

1
2
3
Case 1: 56 58 60 64 65
Case 2: 53 57 58 61 65
Case 3: 90 90 100 106 126

Solution

這題跟 10202 - Pairsumonious Numbers 一樣。

如果將體重、總和排序後 A[]SUM[],保證最小的 A[0] + A[1] = SUM[0],和 A[0] + A[2] = SUM[1] 但是不曉得 A[0] + A[3]A[1] + A[2] 哪個小,因此窮舉 A[1] + A[2] 的結果。

每一次窮舉,可以解出前三小的值,之後就能依序推出所有結果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <stdio.h>
#include <algorithm>
#include <set>
using namespace std;
// same 10202 - Pairsumonious Numbers
int main() {
int n, m, A[50], sum[50];
int testcase, cases = 0;
scanf("%d", &testcase);
while(testcase--) {
n = 5;
m = n*(n-1)/2;
for(int i = 0; i < m; i++)
scanf("%d", &sum[i]);
sort(sum, sum+m);
printf("Case %d:", ++cases);
multiset<int> oRB;
for(int i = 2; i < m; i++)
oRB.insert(sum[i]);
int idx, flag = 0;
for(int i = 2; i < m; i++) { // A[1]+A[2] = sum[i]
if((sum[0]+sum[1]+sum[i])%2)
continue;
int tmp = (sum[0]+sum[1]+sum[i])/2;
A[0] = tmp - sum[i];
A[1] = tmp - sum[1];
A[2] = tmp - sum[0];
multiset<int> RB; // copy
multiset<int>::iterator it;
RB = oRB;
it = RB.find(sum[i]);
RB.erase(it);
int pass = 1;
for(int j = 3; j < n; j++) {
it = RB.begin();// get min
A[j] = (*it) - A[0];
RB.erase(it);
int ok = 1;
for(int k = 1; k < j; k++) { // delete A[j]+A[0-(j-1)]
int tmp = A[j] + A[k];
it = RB.find(tmp);
if(it == RB.end()) {
ok = 0;
break;
}
RB.erase(it);
}
if(!ok) {
pass = 0;
break;
}
}
if(pass) {// output ans
flag = 1;
for(int j = 0; j < n; j++)
printf(" %d", A[j]);
puts("");
break;
}
}
if(!flag)
puts("Impossible");
}
return 0;
}
/*
3
114 116 118 120 121 122 123 124 125 129
110 111 114 115 118 118 119 122 123 126
180 190 190 196 196 206 216 216 226 232
*/