Kickstart Round G 2017 Problem B. Cards Game

来源:互联网 发布:js date 输出格式 编辑:程序博客网 时间:2024/06/05 01:00

Problem B. Cards Game

This contest is open for practice. You can try every problem as many times as you like, though we won't keep track of which problems you solve. Read the Quick-Start Guide to get started.
Small input
15 points
Large input
19 points
Judge's response for last submission: Correct.

Problem

Professor Shekhu was a famous scientist working in the field of game theory in the early days of computer science. Right now, he's working on a game which involves a box containing N distinct cards. The i-th of these cards has a red number written on one side, and a blue number written on the other side. Both of these numbers are positive integers. The game proceeds as follows:

  • The player starts with a total of 0 points. The objective of the game is to finish with the lowest possible total.
  • As long as there are at least two cards remaining in the box, the player must repeat the following move:
    • Remove two cards of their choice from the box. Choose a red number Rfrom one card and a blue number B from the other card.
    • Add the value R ^ B to the total, where ^ denotes bitwise XOR operation.
    • Return one of the two cards to the box, and remove the other from the game.
  • The game ends when there is only one card remaining in the box (and so it is impossible to make another move).

Professor Shekhu has summoned his best student, Akki, to play this game. Can you help Akki find the minimum possible total, considering all possible ways in which he can play the game?

Input

The first line of the input contains an integer T, the number of test cases. T test cases follow; each test case consists of three lines:
First line of the each test case will contain an integer N.

  1. The first line contains a positive integer N: the number of cards in the box.
  2. The second line contains a list of N positive integers Ri; the i-th of these represents the red number on the i-th card.
  3. The third line contains a list of N positive integers Bi; the i-th of these represents the blue number on the i-th card.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the minimum possible total that Akki can attain, if he plays optimally.

Limits

1 ≤ T ≤ 100.
1 ≤ Ri ≤ 109.
1 ≤ Bi ≤ 109.

Small dataset

2 ≤ N ≤ 5.

Large dataset

2 ≤ N ≤ 100.

Sample


Input 
 
Output 
 
221 23 331 101 5013 2 3
Case #1: 1Case #2: 5

In Sample Case #1, Akki has only one move in which he picks up the available cards and has two options.

  1. He can choose red number from the first card and blue number from the second card to add 1 ^ 3 = 2 to the total.
  2. He can choose red number from the second card and blue number from the first card to add 2 ^ 3 = 1 to the total.
The second option is better and the answer is 1.

In Sample Case #2, one optimal strategy is to take the red number from first card and the blue number from second card, add 1 ^ 2 = 3 to the total, and return first card to the box. Then, take the red number from first card and the blue number from third card, add 1 ^ 3 = 2 to the total, and return either of the cards to the box. The final total is 5.

题意:给N张牌,每张正反两面分别是红色蓝色,各有一个数,你每次可以任选2张牌,可以选择一张牌蓝色面数字与另一张牌红色面的数字做异或,结果加到自己的成绩里面去(成绩初始为0),然后扔掉一张牌,放回一张牌,直到

只有一张牌停止。求最终成绩的最小值。


思路:题目开头虽然说博弈游戏,其实是一个人操作,操作n-1次(每次操作扔一张牌,最后剩一张)。

开始只会暴力做。

突破口是根据操作步骤分析,每张扔掉的牌跟留下的牌确立了联系,且联系是有数值的(就是那个异或值),

而留下来的那张牌或者留到最后,或者跟其他牌建立联系然后被扔掉。n-1次操作就建立了n-1条边,关联了n张牌,

最终得到了一棵树。

要求边权和的最小值,其实就是求n个点构成的最小生成树。用kruskal就可以做了。

#include <bits/stdc++.h>using namespace std;const int N = 110;#define PI acos(-1)typedef long long ll;#define INF 0x3f3f3f3fint mod = 1000000007;int r[N], b[N];int fa[N];int find(int x){return fa[x] == x?x :fa[x] = find(fa[x]);}bool merge(int a, int b){a = find(a);b = find(b);if (a != b){fa[a] = b;return true;}return false;}void run(){ int n;vector<tuple<int, int, int> > rec;scanf("%d", &n);for (int i = 0; i < n; i++)scanf("%d", r + i);for (int i = 0; i < n; i++)scanf("%d", b + i);for (int i = 0; i < n; i++){for (int j = i + 1; j < n; j++){rec.emplace_back(min(r[i]^b[j], r[j]^b[i]), i, j);}fa[i] = i;}sort(rec.begin(), rec.end());ll ans = 0;for (auto i : rec){int u, v, w;tie(w, u, v) = i;if (merge(u, v)){ans += w;}}printf("%lld\n", ans);}int main(){freopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);int T, cas = 1;scanf("%d", &T);while (T--){ printf("Case #%d: ", cas++);run();}    return 0;}





阅读全文
0 0