UVA 10542 - Hyper-drive(容斥原理)

UVA 10542 - Hyper-drive

题目链接

题意:给定一些个d维的方块,给定两点,求穿过多少方块

思路:容斥原理,每次选出一些维度,如果gcd(a, b),就会穿过多少点,对应的就减少穿过多少方块,所以最后得到式子d1 + d2 + .. dn - gcd(d1, d2)..+gcd(d1, d2, d3)...

代码:

#include <cstdio>
#include <cstring>

typedef long long ll;

int t, d, a[15];

int bitcount(int x) {
	int ans = 0;
	while (x) {
		ans += (x&1);
		x >>= 1;
	}
	return ans;
}

int gcd(int a, int b) {
	while (b) {
		int tmp = a % b;
		a = b;
		b = tmp;
	}
	return a;
}

int main() {
	int cas = 0;
	scanf("%d", &t);
	while (t--) {
		scanf("%d", &d);
		for (int i = 0; i < d; i++)
			scanf("%d", &a[i]);
		int tmp;
		for (int i = 0; i < d; i++) {
			scanf("%d", &tmp);
			a[i] -= tmp;
			if (a[i] < 0) a[i] = -a[i];
		}
		ll ans = 0;
		for (int i = 0; i < (1<<d); i++) {
			int cnt = bitcount(i);
			int sum = 0;
			for (int j = 0; j < d; j++) {
				if (i&(1<<j))
					sum = gcd(sum, a[j]);
			}
			if (cnt&1) ans += sum;
			else ans -= sum;
		}
		printf("Case %d: %lld\n", ++cas, ans);
	}
	return 0;
}
时间: 2024-10-23 04:58:40

UVA 10542 - Hyper-drive(容斥原理)的相关文章

uva 10542 - Hyper-drive(容斥)

题目链接:uva 10542 - Hyper-drive 题目大意:给定n维空间的线段,问说线段经过几个格子. 解题思路:对于线段可以将一点移动至原点,变成 (0,0)到(a,b)这条线段,以二维为例,每次会从一个格子移动到另一个格子,可以是x+1坐标,也可以是y+1,所以总的应该是a+b-1,扣除掉x+1,y+1的情况gcd(a,b)-1 (原点).映射成n维就要用容斥原理计算结果. /*********************** * (0, 0, 0, ...) -> (a, b, c,

UVA 10458 - Cricket Ranking(容斥原理)

UVA 10458 - Cricket Ranking 题目链接 题意:给定k个区间,要求用这些数字范围去组合成n,问有几种组合方式 思路:容斥原理,容斥是这样做:已知n个组成s,不限值个数的话,用隔板法求出情况为C(s + n - 1, n - 1),但是这部分包含了超过了,那么就利用二进制枚举出哪些是超过的,实现把s减去f(i) + 1这样就保证这个位置是超过的,减去这部分后,有多减的在加回来,这就满足了容斥原理的公式,个数为奇数的时候减去,偶数的时候加回 代码: #include <cst

uva 11488 - Hyper Prefix Sets(字典树)

H Hyper Prefix Sets Prefix goodness of a set string is length of longest common prefix*number of strings in the set. For example the prefix goodness of the set {000,001,0011} is 6.You are given a set of binary strings. Find the maximum prefix goodnes

uva 12075 - Counting Triangles(容斥原理)

题目链接:uva 12075 - Counting Triangles 题目大意:一个n?m的矩阵,求说有选任意三点,可以组成多少个三角形. 解题思路:任意选三点C(3(n+1)?(m+1))但是有些组合是不可行得,即为三点共线,除了水平和竖直上的组合,就是斜线上的了,dp[i][j]即为ij情况下的斜线三点共线. #include <cstdio> #include <cstring> typedef long long ll; const int N = 1005; ll dp

Uva 10325 The Lottery ( 容斥原理 )

Uva 10325 The Lottery ( 容斥原理 ) #include <cstdio> #include <cstring> typedef long long LL; LL x[20],n, m; LL gcd( LL a, LL b ) { return ( b == 0 ) ? a : gcd( b, a % b ); } LL lcm( LL a, LL b ) { return a / gcd( a, b ) * b; } void solve() { LL a

UVA 11488 Hyper Prefix Sets (Trie)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2483 Hyper Prefix Sets Prefix goodness of a set string islength of longest common prefix*number of strings in the set.For example the prefix goodnes

UVa 11806 拉拉队(容斥原理)

https://vjudge.net/problem/UVA-11806 题意: 在一个m行n列的矩形网格里放k个相同的石子,有多少种方法?每个格子最多放一个石子,所有石子都要用完,并且第一行.最后一行.第一列.最后一列都得有石子. 思路: 如果考虑各种情况的话很复杂,设满足第一行没有石子的方案集为A,最后一行没有石子的方案集为B,第一列没有石子的方案集为C,最后一列没有石子的方案集为D,全集为S. 一个容斥原理的公式就可以解答出来,用二进制来枚举方案集的组合. 1 #include <iost

UVA - 11806 Cheerleaders (容斥原理)

题意:在N*M个方格中放K个点,要求第一行,第一列,最后一行,最后一列必须放,问有多少种方法. 分析: 1.集合A,B,C,D分别代表第一行,第一列,最后一行,最后一列放. 则这四行必须放=随便放C[N * M][K] - 至少有一行没放,即ABCD=随便放-A的补集 ∪ B的补集 ∪ C的补集 ∪ D的补集. 2.A的补集 ∪ B的补集 ∪ C的补集 ∪ D的补集,可用容斥原理计算,二进制枚举即可. #include<cstdio> #include<cstring> #incl

UVa 11488 Hyper Prefix Sets

方法:Trie 本题其实就是trie的实现,每个节点需要记录两个值,深度 和 visit的次数,答案便是 max(深度 * visit的次数). 数组实现code: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <string> #include <vector> #include <stack>