AtCoder Beginner Contest 190 A~D 题解

46 篇文章 7 订阅
43 篇文章 5 订阅

A - Very Very Primitive Game

题目大意

Takahashi和Aoki在玩一个游戏。
游戏规则是这样的:

  • 最开始,Takahashi和Aoki分别有 A A A B B B颗糖。
  • 他们将轮流吃一颗糖,第一个无法吃糖的人算输。如果 C = 0 C=0 C=0,那么Takahashi先吃;如果 C = 1 C=1 C=1,那么Aoki先吃。

请输出最终胜者的名字。

0 ≤ A , B ≤ 100 0\le A,B\le 100 0A,B100
C ∈ { 0 , 1 } C \in \{0,1\} C{0,1}

输入格式

A   B   C A~B~C A B C

输出格式

输出答案。

样例

ABC输出
210Takahashi
220Aoki
221Takahashi

分析

可以看出,如果是Aoki先吃( C = 1 C=1 C=1),那么当 B > A B>A B>A时,Aoki会赢。那么如果Takahashi先吃( C = 1 C=1 C=1),我们可以先将 B B B加上 1 1 1,这时就变成了前一种情况,再判断 B > A B>A B>A是否成立即可。

代码

#include <cstdio>
using namespace std;

int main(int argc, char** argv)
{
	int a, b, c;
	scanf("%d%d%d", &a, &b, &c);
	if(c == 0) b ++;
	puts(b > a? "Aoki": "Takahashi");
	return 0;
}

B - Magic 3

题目大意

一位魔术师要与怪兽战斗。
他可以使用 N N N种咒语。
i i i个咒语的冷却时间是 X i X_i Xi秒、伤害是 Y i Y_i Yi
但是,这个怪兽可以免疫冷却时间不少于 S S S或伤害不超过 D D D的任何咒语的伤害。
这位魔术师能伤害到怪兽吗?

1 ≤ N ≤ 100 1\le N\le 100 1N100
1 ≤ X i , Y i ≤ 1 0 9 1\le X_i, Y_i\le 10^9 1Xi,Yi109
1 ≤ S , D ≤ 1 0 9 1\le S, D\le 10^9 1S,D109

输入格式

N   S   D N~S~D N S D
X 1   Y 1 X_1~Y_1 X1 Y1
X 2   Y 2 X_2~Y_2 X2 Y2
⋮ \vdots
X N   Y N X_N~Y_N XN YN

输出格式

如果魔术师能伤害到怪物,输出Yes;否则,输出No

样例

样例输入1

4 9 9
5 5
15 5
5 15
15 15

样例输出1

Yes

S = D = 9 S=D=9 S=D=9,则:

咒语编号冷却时间伤害能否伤害到怪物
1 1 1 5 5 5     ✓ ~~~\checkmark     5     × 5~~~\bm\times 5   × × \bm\times ×
2 2 2 15 15 15     × ~~~\bm\times    × 5     × 5~~~\bm\times 5   × × \bm\times ×
3 3 3 5 5 5     ✓ ~~~\checkmark     15     ✓ 15~~~\checkmark 15    ✓ \checkmark
4 4 4 15 15 15     × ~~~\bm\times    × 15     ✓ 15~~~\checkmark 15    × \bm\times ×

样例输入2

3 691 273
691 997
593 273
691 273

样例输出2

No

样例输入3

7 100 100
10 11
12 67
192 79
154 197
142 158
20 25
17 108

样例输出3

Yes

只有第七个咒语能伤害怪兽。

分析

这题可以遍历每一个 i i i,并判断如果 X i < S X_i<S Xi<S Y i > D Y_i>D Yi>D同时成立,输出Yes;当所有 i i i都不符合条件时,输出No

代码

我写的这个代码是在输入时处理的,当然也可以输入之后再处理。

#include <cstdio>
using namespace std;

int main(int argc, char** argv)
{
	int n, s, d;
	scanf("%d%d%d", &n, &s, &d);
	while(n--)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		if(x < s && y > d)
		{
			puts("Yes");
			return 0;
		}
	}
	puts("No");
	return 0;
}

C - Bowls and Dishes

题目大意

N N N个编号为 1 , 2 , … , N 1,2,\dots,N 1,2,,N的盘子和 M M M个编号为 1 , 2 , … , M 1,2,\dots,M 1,2,,M的条件。
当编号为 A i A_i Ai B i B_i Bi的盘子中都有(至少一个)球时,第 i i i个条件就被满足了。
K K K个编号为 1 , 2 , … , K 1,2,\dots,K 1,2,,K的人。第 i i i个人会将一个球放入编号为 C i C_i Ci D i D_i Di的盘子中。
最多能有多少个条件被满足?

2 ≤ N ≤ 100 2\le N\le 100 2N100
1 ≤ M ≤ 100 1\le M\le 100 1M100
1 ≤ A i < B i ≤ N 1\le A_i<B_i\le N 1Ai<BiN
1 ≤ K ≤ 16 1\le K\le 16 1K16
1 ≤ C i < D i ≤ N 1\le C_i<D_i\le N 1Ci<DiN

输入格式

N   M N~M N M
A 1   B 1 A_1~B_1 A1 B1
⋮ \vdots
A M   B M A_M~B_M AM BM
K K K
C 1   D 1 C_1~D_1 C1 D1
⋮ \vdots
C K   D K C_K~D_K CK DK

输出格式

输出答案。

样例

样例输入1

4 4
1 2
1 3
2 4
3 4
3
1 2
1 3
2 3

样例输出1

2

如果编号为 1 , 2 , 3 1,2,3 1,2,3的人将他们的球分别放入编号为 1 , 3 , 2 1,3,2 1,3,2的盘子中,则条件 1 1 1 2 2 2将被满足。

样例输入2

4 4
1 2
1 3
2 4
3 4
4
3 4
1 2
2 4
2 4

样例输出2

4

如果编号为 1 , 2 , 3 , 4 1,2,3,4 1,2,3,4的人将他们的球分别放入编号为 3 , 1 , 2 , 4 3,1,2,4 3,1,2,4的盘子中,则所有条件将被满足。

样例输入3

6 12
2 3
4 6
1 2
4 5
2 6
1 5
4 5
1 3
1 2
2 6
2 3
2 5
5
3 5
1 4
2 6
4 6
5 6

样例输出3

9

分析

这个题数据范围很小,所以我们考虑枚举。
我们可以按人枚举,枚举第 i i i个人是将自己的球放入编号为 C i C_i Ci还是 D i D_i Di的盘子。
每个人有选 C i C_i Ci D i D_i Di两种情况,所以枚举次数为 2 K 2^K 2K,而题目保证 1 ≤ K ≤ 16 1\le K\le16 1K16,所以不会超时。
我们可以使用二进制法来枚举:

  • K K K个二进制位。
  • i i i个二进制位如果是 1 1 1,则第 i i i个人将球放入编号为 C i C_i Ci的盘子;否则,他会把球放入编号为 D i D_i Di的盘子。

总时间复杂度为 O ( M 2 K ) \mathcal O(M2^K) O(M2K)

代码

#include <cstdio>
#include <cstring>
using namespace std;

int a[105], b[105], c[20], d[20];

int main(int argc, char** argv)
{
	int n, m, k;
	scanf("%d%d", &n, &m);
	for(int i=0; i<m; i++)
	{
		scanf("%d%d", a + i, b + i);
		a[i] --, b[i] --;
	}
	scanf("%d", &k);
	for(int i=0; i<k; i++)
	{
		scanf("%d%d", c + i, d + i);
		c[i] --, d[i] --;
	}
	int limit = 1 << k, ans = 0;
	for(int st=0; st<limit; st++)
	{
		bool hasdish[105] = {false};
		for(int i=0; i<k; i++)
			if(st & (1 << i))
				hasdish[c[i]] = true;
			else hasdish[d[i]] = true;
		int cnt = 0;
		for(int i=0; i<m; i++)
			cnt += hasdish[a[i]] && hasdish[b[i]];
		if(cnt > ans) ans = cnt;
	}
	printf("%d\n", ans);
	return 0;
}

D - Staircase Sequences

题目大意

有多少个和为 N N N、公差为 1 1 1的等差数列?
1 ≤ N ≤ 1 0 12 1\le N\le 10^{12} 1N1012

输入格式

N N N

输出格式

输出答案。

样例

N输出
12 12 12 4 4 4
1 1 1 2 2 2
63761198400 63761198400 63761198400 1920 1920 1920

分析

我们设和为 N N N、公差为 1 1 1的等差数列为 [ a , b ] [a,b] [a,b],则
( a + b ) ( b − a + 1 ) 2 = N \frac {(a+b)(b-a+1)} 2=N 2(a+b)(ba+1)=N
( a + b ) ( b − a + 1 ) = 2 N {(a+b)(b-a+1)}=2N (a+b)(ba+1)=2N
所以,我们求 2 N 2N 2N的奇偶性不同的因子对数即可。这里注意,题目里的等差数列是可以有负数的,所以最终结果一定要乘 2 2 2
代码总时间复杂度为 O ( n ) \mathcal O(\sqrt n) O(n )

代码

请注意一定要使用long long

#include <cstdio>
using namespace std;

typedef long long LL;

int main(int argc, char** argv)
{
	LL n;
	scanf("%lld", &n);
	n <<= 1LL;
	int cnt = 0;
	for(LL i=1; i*i<=n; i++)
		if(n % i == 0 && i % 2 != n / i % 2)
			cnt ++;
	printf("%d\n", cnt << 1);
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值