ABC190 A~D
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
0≤A,B≤100
C
∈
{
0
,
1
}
C \in \{0,1\}
C∈{0,1}
输入格式
A B C A~B~C A B C
输出格式
输出答案。
样例
A | B | C | 输出 |
---|---|---|---|
2 | 1 | 0 | Takahashi |
2 | 2 | 0 | Aoki |
2 | 2 | 1 | Takahashi |
分析
可以看出,如果是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
1≤N≤100
1
≤
X
i
,
Y
i
≤
1
0
9
1\le X_i, Y_i\le 10^9
1≤Xi,Yi≤109
1
≤
S
,
D
≤
1
0
9
1\le S, D\le 10^9
1≤S,D≤109
输入格式
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
2≤N≤100
1
≤
M
≤
100
1\le M\le 100
1≤M≤100
1
≤
A
i
<
B
i
≤
N
1\le A_i<B_i\le N
1≤Ai<Bi≤N
1
≤
K
≤
16
1\le K\le 16
1≤K≤16
1
≤
C
i
<
D
i
≤
N
1\le C_i<D_i\le N
1≤Ci<Di≤N
输入格式
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
1≤K≤16,所以不会超时。
我们可以使用二进制法来枚举:
- 有 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}
1≤N≤1012
输入格式
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)(b−a+1)=N
(
a
+
b
)
(
b
−
a
+
1
)
=
2
N
{(a+b)(b-a+1)}=2N
(a+b)(b−a+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;
}