11

Google APAC 2017 Problem B. Robot Rock Band(位运算)

 3 years ago
source link: https://arminli.com/google-apac-2017-b/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Armin's Blog

Google APAC 2017 Problem B. Robot Rock Band(位运算)

September 05, 2016

题目链接

题意:四组数字,每组都是 n 个数,要求从每组数中选一个数字,四个数的异或结果等于 k。

一开始在想拆位,后来发现没那么麻烦。

n < 1000,四层循环肯定超时,所以把四组数字分成两次计算异或。

异或性质:x^y^y = x

假设前两组数的异或结果为 x,后两组数字中的异或结果为 y,那么题目就是要求 x^y=k. 即 y=k^x.

所以把所有 x^k 计算出来,用 map 对应 x^k 的个数,然后再遍历后两组出直接取出 map[y],看存在几次,全部加在一起。(栈区定义 map 默认初始化为 0,因此若不存在加的就是 0)。

注意 ans 要开 long long。

#include <cstring>
#include <map>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <iostream>
using namespace std;
int main(){
	freopen("../Downloads/B-large-practice.in", "r", stdin);
	freopen("ans.out", "w", stdout);
	int t; cin >> t;
	for(int cas = 1; cas <= t; cas++){
		int n, k;
		scanf("%d %d", &n, &k);
		int a[4005];
		for(int i = 0; i < 4*n; i++){
			scanf("%d", &a[i]);
		}
		map<int, int> m;
		for(int i = 0; i < n; i++){
			for(int j = n; j < 2*n; j++){
				int cal = a[i]^a[j]^k;
				int tmp = m[cal];
				m[cal] = tmp+1;
			}
		}
		//cout << m[0]<< endl;
		long long ans = 0;
		for(int i = 2*n; i < 3*n; i++){
			for(int j = 3*n; j < 4*n; j++){
				ans += m[a[i]^a[j]];
			//	cout << ans << endl;
			}
		}
		printf("Case #%d: %lld\n", cas, ans);
	}
	return 0;
}


Profile picture

Written by Armin Li , a venture capitalist. [Weibo] [Subscribe]


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK