UESTC - 第12届 ACM 趣味赛一

A

B

先假设没有 ”知道这 \(n\) 个人中普通市民的人数一定不少于组织中的人“ 这个条件,我们考虑为什么没有办法将任何人的身份识别出来。不妨这样想:每一个人只有两种情况,要么说谎话,要么说真话,而所有说谎话的人和所有说真话的人给出的答案都会是一样的。也就是说,我们只可能得到两种答案,要么是真实的情况,要么是真实的情况取反(即,说谎话会被认为是说真话,说真话会被认为是说假话)。很显然对于这两种答案我们没法判断出那个是正确的,但是我们可以获得一个信息,也就是这群人已经被分为两群,要么其中一群是诚实的,另一群是不诚实的;要么其中一群是不诚实的,另一群是诚实的。现在加上前面提到的那个条件,我们发现当这两群人人数不等的时候,人数多的一定是普通市民;只有当人数相等的时候,无法将这两群人归类,此时总人数为偶数。答案显然。

C

方法一

\(f[i][j]\) 表示前 \(i\) 关 Kaiser 玩 \(j\) 局而 Fatdog_Jo 玩 \(i-j\) 局的最少时间,则转移方程为 \(f[i][j]=max\{f[i-1][j]+b[i],f[i-1][j-1]+a[i]\}\) ,该方法时间复杂度为 \(O(n^2)\)

方法二

先假设所有关都由 Fatdog_Jo 来玩,则 \(ans=\sum b[i]\)。设 \(c[i]=a[i]-b[i]\),则若第 \(i\) 关由 Kaiser 来玩,我们只需将 \(ans+=c[i]\)。现在有 \(n/2\) 关需要 Kaiser 来玩,我们只需要从 \(c[i]\) 中选出最小的 \(n/2\) 个加上去即可。该方法时间复杂度为 \(O(n\log n)\) 优于方法一。

D

暴力枚举旋风斩的回合数即可,显然最多不超过 \(5000\) 次旋风斩所有随从会死亡。时间复杂度为 \(O(na)\)

E

\(t\) 时刻成员 \(0\) 与成员 \(1\) 相遇,列出方程组:

1:\(y_0=ax_0+b\)

2:\(y_1=ax_1+b\)

3:\(x_0+v_{x_0}t=x_1+v_{x_1}t\)

4:\(y_0+v_{y_0}t=y_1+v_{y_1}t\)

由 3 得 \(x_0-x_1=-t(v_{x_0}-v_{x_1})\)

由 4 得 \(y_0-y_1=-t(v_{y_0}-v_{y_1})\)

两式相除,整理得 \(v_{y_0}-v_{y_1}=a(v_{x_0}-v_{x_1})\)

移项得 \(v_{y_0}-av_{x_0}=v_{y_1}-av_{x_1}\)

即当上式成立(两直线平行除外)时两个成员相遇。特判一下平行的情况以及 \(a=0\) 的情况即可(\(Upd\)\(a=0\)不用特判)。

Code

#include <cstdio>
#include <map>
#include <utility>
using namespace std;

int n, a, b, x, y;
long long ans;
map<int, int> mp;
map<pair<int, int>, int> mppar;

int main(){
	scanf("%d%d%d", &n, &a, &b);
	if(!a){
		for(int i = 0; i < n; i++){
			scanf("%d%d%d", &x, &x, &y);
			ans += mp[y] - mppar[make_pair(x, y)];
			mp[y]++, mppar[make_pair(x, y)]++;
		}
	}else for(int i = 0; i < n; i++){
		scanf("%d%d%d", &x, &x, &y);
		ans -= mppar[make_pair(x, y)];
		mppar[make_pair(x, y)]++;
		x = y - a * x;
		ans += mp[x];
		mp[x]++;
	}
	printf("%lld", ans << 1);
	return 0;
}
posted @ 2021-11-26 17:05  SpaceJellyfish  阅读(127)  评论(0编辑  收藏  举报