赞
踩
有一位魔术师,他正在打一个血量为
H
H
H?的怪兽。
当怪兽的血量是
M
M
M的倍数时,魔术师能打败怪兽。
魔术师能打败怪兽吗?
1 ≤ M , H ≤ 1000 1\le M,H\le 1000 1≤M,H≤1000
M H M~H M H
如果魔术师能打败怪兽,输出Yes
;如果不能,输出No
。
M M M | H H H | 输出 |
---|---|---|
10 10 10 | 120 120 120 | Yes |
10 10 10 | 125 125 125 | No |
只需判断 H H H是否是 M M M的倍数即可。
#include <cstdio>
using namespace std;
int main()
{
int m, h;
scanf("%d%d", &m, &h);
puts(h % m == 0? "Yes": "No");
return 0;
}
我们有很多橙子。每个橙子的重量在
A
A
A克到
B
B
B克之间(包含
A
A
A、
B
B
B克,可能为小数)。
这些橙子的总重量为
W
W
W千克。
找到橙子最少和最多的数量。
1
≤
A
≤
B
≤
1000
1\le A\le B\le 1000
1≤A≤B≤1000
1
≤
W
≤
1000
1\le W\le 1000
1≤W≤1000
A B W A~B~W A B W
输出橙子最少和最多的数量,用一个空格隔开;如果数据不合法,输出UNSATISFIABLE
。
A A A | B B B | W W W | 输出 |
---|---|---|---|
100 100 100 | 200 200 200 | 2 2 2 | 10 20 10~20 10 20 |
120 120 120 | 150 150 150 | 2 2 2 | 14 16 14~16 14 16 |
300 300 300 | 333 333 333 | 1 1 1 | UNSATISFIABLE |
如果要得到最小的结果,那么每个橙子的单价必定要取最大值。所以,我们设
m
i
n
=
⌈
W
B
⌉
min=\lceil\frac WB\rceil
min=⌈BW⌉。
同理,如果要得到最大的结果,那么每个橙子的单价必定要取最小值。所以,我们设
m
a
x
=
⌊
W
A
⌋
max=\lfloor\frac WA\rfloor
max=⌊AW⌋。
计算完成后,如果
m
i
n
>
m
a
x
min>max
min>max,说明数据不合法;否则,输出
m
i
n
min
min和
m
a
x
max
max。
#include <cstdio>
using namespace std;
int main()
{
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
w *= 1000;
int min = w % b == 0? w / b: w / b + 1;
int max = w / a;
if(min > max) puts("UNSATISFIABLE");
else printf("%d %d\n", min, max);
return 0;
}
我们写一个整数时,可以从右开始每隔三位写一个逗号。如,
1234567
1234567
1234567写作1,234,567
、
777
777
777直接写作777
。
如果我们写下
1
1
1到
N
N
N之间的所有整数,一共要用多少个逗号?
1 ≤ N ≤ 1 0 15 1\le N\le 10^{15} 1≤N≤1015
N N N
输出总共需要的逗号的数量。
N N N | 输出 |
---|---|
1010 1010 1010 | 11 11 11 |
27182818284590 27182818284590 27182818284590 | 107730272137364 107730272137364 107730272137364 |
我们可以按位置数逗号的数量。首先,在从右往左数的第一个逗号的位置,只要大于 1000 1000 1000的数都需要写逗号。以此类推,在从右往左数的第 N N N个逗号的位置,只要大于 100 0 N 1000^N 1000N的数都需要写逗号。这样,我们就可以通过上述算法写出代码了。
#include <cstdio>
using namespace std;
typedef long long LL;
int main()
{
LL n, ans = 0LL;
scanf("%lld", &n);
for(LL p=1000LL; p<=n; p*=1000LL)
ans += n - p + 1;
printf("%lld\n", ans);
return 0;
}
我们有
N
N
N个包裹(包裹
1
1
1,……,包裹
N
N
N)和
M
M
M个盒子(盒子
1
1
1,……,盒子
N
N
N)。
第
i
i
i个包裹的大小和价值分别是
W
i
W_i
Wi和
V
i
V_i
Vi。
第
i
i
i个盒子最多只能装一个大小为
X
i
X_i
Xi的包裹。
给你
Q
Q
Q组询问,每组包含两个整数
L
L
L和
R
R
R,请回答下列问题:
1
≤
N
,
M
,
Q
≤
50
1\le N,M,Q\le 50
1≤N,M,Q≤50
1
≤
W
i
,
V
i
,
X
i
≤
1
0
6
1\le W_i,V_i,X_i\le 10^6
1≤Wi,Vi,Xi≤106
1
≤
L
≤
R
≤
M
1\le L\le R\le M
1≤L≤R≤M
N
M
Q
N~M~Q
N M Q
W
1
V
1
W_1~V_1
W1 V1
⋮
\vdots
⋮
W
N
V
N
W_N~V_N
WN VN
X
1
…
X
M
X_1~\dots~X_M
X1 … XM
L
1
R
1
L_1~R_1
L1 R1
⋮
\vdots
⋮
L
Q
R
Q
L_Q~R_Q
LQ RQ
输出 Q Q Q行。第 i i i行应该包含 L i L_i Li和 R i R_i Ri这个询问对应的答案。
3 4 3
1 9
5 3
7 8
1 8 6 9
4 4
1 4
1 3
20
0
9
这道题看似很像背包问题,其实不然。我们只需升序排序数组 X X X后,再按顺序贪心地为每个盒子选择它能拿到的价值最高的包裹即可。总时间复杂度为 O ( N M Q ) \mathcal O(NMQ) O(NMQ)。
#include <cstdio> #include <algorithm> #define maxn 55 using namespace std; typedef pair<int, int> pii; pii bags[maxn], boxes[maxn]; bool taken[maxn]; int main() { int n, m, q; scanf("%d%d%d", &n, &m, &q); for(int i=0; i<n; i++) scanf("%d%d", &bags[i].second, &bags[i].first); sort(bags, bags + n, greater<pii>()); for(int i=0; i<m; i++) scanf("%d", &boxes[i].first), boxes[i].second = i; sort(boxes, boxes + m); while(q--) { int l, r, ans = 0; scanf("%d%d", &l, &r); l --, r --; fill(taken, taken + n, false); for(int i=0; i<m; i++) { auto [size, idx] = boxes[i]; if(idx < l || idx > r) { int j = 0; for(; j<n; j++) if(!taken[j] && bags[j].second <= size) break; if(j < n) ans += bags[j].first, taken[j] = true; } } printf("%d\n", ans); } return 0; }
我们有一个长度为
N
N
N、由数字0~9
组成的字符串
S
S
S,和一个长度同样为
N
N
N、由A
和T
组成的字符串
X
X
X。
Takahashi和Aoki要用这两个字符串玩一个
N
N
N轮的游戏。最开始,他们有一个空的字符串
T
T
T。在第
i
i
i轮(
1
≤
i
≤
N
1\le i\le N
1≤i≤N),他们要做下列事情:
A
,Aoki执行下面的操作;如果
X
i
X_i
Xi为T
,则Takahashi执行下面的操作:0
加到
T
T
T的后面。在
N
N
N个操作之后,
T
T
T会变成一个数字0~9
组成的字符串。如果我们把它看成一个十进制数(去掉前导
0
0
0),那么如果这个数为
7
7
7的倍数,则Takahashi胜;相反,如果这个数不为
7
7
7的倍数,则Aoki胜。
判断当两个人都按照最优操作进行游戏时,谁会赢。
1
≤
N
≤
1
0
5
1\le N\le 10^5
1≤N≤105
∣
S
∣
=
∣
X
∣
=
N
|S|=|X|=N
∣S∣=∣X∣=N
N
N
N
S
S
S
X
X
X
输出胜者的名字(Takahashi
或者Aoki
)。
略,请自行前往AtCoder查看
这题首先很容易想到使用搜索。我们定义
w
i
n
n
e
r
(
i
,
r
)
=
\mathrm{winner}(i,r)=~
winner(i,r)= 在第
i
i
i轮
T
m
o
d
7
=
r
T\bmod7=r
Tmod7=r最终的赢家。
我们会发现,由于
r
r
r只有
0
0
0~
6
6
6,计算重复率较高,所以这题可以使用记忆化搜索来解决。
#include <cstdio> #include <cstring> #define AO 0 #define TA 1 #define maxn 200005 using namespace std; char s[maxn], x[maxn]; int n, dp[maxn][7]; int winner(int i, int r) { if(dp[i][r] != -1) return dp[i][r]; if(i >= n) return dp[i][r] = r == 0; if(winner(i + 1, 10 * r % 7) == TA) { if(x[i] == 'T') return dp[i][r] = TA; } else if(x[i] == 'A') return dp[i][r] = AO; if(winner(i + 1, (10 * r + s[i] - '0') % 7) == TA) { if(x[i] == 'T') return dp[i][r] = TA; } else if(x[i] == 'A') return dp[i][r] = AO; return dp[i][r] = x[i] == 'A'; } int main() { scanf("%d%s%s", &n, s, x); memset(dp, -1, sizeof(dp)); puts(winner(0, 0) == TA? "Takahashi": "Aoki"); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。