AtCoder Beginner Contest 205 A~E 题解

A - kcal

题目大意

我们有一种每 100 100 100毫升含有 A A A千卡热量的饮料。 B B B毫升的这种饮料含有多少千卡热量?

0 ≤ A , B ≤ 1000 0\le A, B\le 1000 0A,B1000

输入格式

A   B A~B A B

输出格式

输出 B B B毫升这种饮料包含的的千卡数。最大允许浮点数精度误差 1 0 − 6 10^{-6} 106

样例

A A A B B B输出
45 45 45 200 200 200 90 90 90
37 37 37 450 450 450 166.5 166.5 166.5
0 0 0 1000 1000 1000 0 0 0
50 50 50 0 0 0 0 0 0

分析

废话不多说,答案就是 A B 100 \frac{AB}{100} 100AB~

代码

#include <cstdio>
using namespace std;

int main()
{
	int a, b;
	scanf("%d%d", &a, &b);
	a *= b;
	printf("%d.%d\n", a / 100, a % 100);
	return 0;
}

B - Permutation Check

题目大意

给定长度为 N N N的序列 A = ( A 1 , A 2 , … , A N ) A=(A_1,A_2,\dots,A_N) A=(A1,A2,,AN)
判断 A A A是否为 ( 1 , 2 , … , N ) (1,2,\dots,N) (1,2,,N)的一种排列。

1 ≤ A i ≤ N ≤ 1 0 3 1\le A_i\le N\le 10^3 1AiN103

输入格式

N N N
A 1   A 2   …   A N A_1~A_2~\dots~A_N A1 A2  AN

输出格式

如果 A A A ( 1 , 2 , … , N ) (1,2,\dots,N) (1,2,,N)的一种排列,输出Yes;否则,输出No

样例

样例输入1

5
3 1 2 4 5

样例输出1

Yes

( 3 , 1 , 2 , 4 , 5 ) (3,1,2,4,5) (3,1,2,4,5) ( 1 , 2 , 3 , 4 , 5 ) (1,2,3,4,5) (1,2,3,4,5)的一种排列,所以我们输出Yes

样例输入2

6
3 1 4 1 5 2

样例输出2

No

( 3 , 1 , 4 , 1 , 5 , 2 ) (3,1,4,1,5,2) (3,1,4,1,5,2)不是 ( 1 , 2 , 3 , 4 , 5 , 6 ) (1,2,3,4,5,6) (1,2,3,4,5,6)的一种排列,所以我们输出No

样例输入3

3
1 2 3

样例输出3

Yes

样例输入4

1
1

样例输出4

Yes

分析

由于题目保证 1 ≤ A i ≤ N 1\le A_i\le N 1AiN,所以 ( 1 , 2 , … , N ) (1,2,\dots,N) (1,2,,N)的一种排列 A A A定义如下:

  • A A A 1 1 1 N N N每个数字不重复出现。

因此,我们可以用数组记录每个数字是否出现,所以总时间复杂度为 O ( n ) \mathcal O(n) O(n)

代码

#include <cstdio>
#define maxn 1005
using namespace std;

bool used[maxn];

int main()
{
	int n;
	scanf("%d", &n);
	for(int i=0; i<n; i++)
	{
		int a;
		scanf("%d", &a);
		if(used[a])
		{
			puts("No");
			return 0;
		}
		used[a] = true;
	}
	puts("Yes");
	return 0;
}

C - POW

题目大意

给定三个整数 A , B , C A,B,C A,B,C,判断 A C A^C AC B C B^C BC哪个更大。

− 1 0 9 ≤ A , B ≤ 1 0 9 -10^9\le A,B\le 10^9 109A,B109
1 ≤ C ≤ 1 0 9 1\le C\le 10^9 1C109

输入格式

A   B   C A~B~C A B C

输出格式

本题分如下三种情况输出:

  • 如果 A C < B C A^C<B^C AC<BC,输出<
  • 如果 A C > B C A^C>B^C AC>BC,输出>
  • 如果 A C = B C A^C=B^C AC=BC,输出=

样例

A A A B B B C C C输出
3 3 3 2 2 2 4 4 4>
− 7 -7 7 7 7 7 2 2 2=
− 8 -8 8 6 6 6 3 3 3<

分析

首先,由于负负得正 ( − a ) 2 = a 2 (-a)^2=a^2 (a)2=a2
这样,我们可以根据奇偶性得出,如果 n n n为偶数, ( − a ) n = a n (-a)^n=a^n (a)n=an;但如果 n n n为奇数,则 ( − a ) n = − ( a n ) (-a)^n=-(a^n) (a)n=(an)
因此,我们只需判断如果 C C C为偶数,将 A A A替换为 ∣ A ∣ |A| A,再将 B B B替换为 ∣ B ∣ |B| B
最后, A A A B B B的大小关系就是 A C A^C AC B C B^C BC的大小关系。

代码

#include <cstdio>
using namespace std;

int main()
{
	int a, b, c;
	scanf("%d%d%d", &a, &b, &c);
	if(!(c & 1))
	{
		if(a < 0) a = -a;
		if(b < 0) b = -b;
	}
	puts(a < b? "<": a > b? ">": "=");
	return 0;
}

D - Kth Excluded

题目大意

给定长度为 N N N的正整数序列 A = ( A 1 , A 2 , … , A N ) A=(A_1,A_2,\dots,A_N) A=(A1,A2,,AN) Q Q Q次查询。
在第 i i i次查询中,给定正整数 K i K_i Ki,求第 K i K_i Ki小的不在 A A A中的正整数。

1 ≤ N , Q ≤ 1 0 5 1\le N,Q\le 10^5 1N,Q105
1 ≤ A 1 < A 2 < ⋯ < A N ≤ 1 0 18 1\le A_1<A_2<\dots<A_N\le10^{18} 1A1<A2<<AN1018
1 ≤ K i ≤ 1 0 18 1\le K_i\le 10^{18} 1Ki1018

输入格式

N   Q N~Q N Q
A 1   A 2   …   A N A_1~A_2~\dots~A_N A1 A2  AN
K 1 K_1 K1
K 2 K_2 K2
⋮ \hspace{5pt}\vdots
K N K_N KN

输出格式

输出 Q Q Q行。第 i i i行应该包含第 K i K_i Ki小的不在 A A A中的正整数。

样例

样例输入1

4 3
3 5 6 7
2
5
3

样例输出1

2
9
4

不在 A A A中的正整数有 1 , 2 , 4 , 8 , 9 , 10 , 11 , … 1,2,4,8,9,10,11,\dots 1,2,4,8,9,10,11,,其中有:

  • 2 2 2小的 2 2 2
  • 5 5 5小的 9 9 9
  • 3 3 3小的 4 4 4

因此,我们应该依次输出294

样例输入2

5 2
1 2 3 4 5
1
10

样例输出2

6
15

分析

本题我们可以先预处理出 A A A中每个元素比它小的元素的数量,再二分查找即可。

代码

#include <cstdio>
#include <algorithm>
#define maxn 100005
using namespace std;

using LL = long long;
LL a[maxn];

int main()
{
	int n, q;
	scanf("%d%d", &n, &q);
	for(int i=0; i<n; i++)
	{
		scanf("%lld", a + i);
		a[i] -= i;
	}
	while(q--)
	{
		LL k;
		scanf("%lld", &k);
		printf("%lld\n", k + (upper_bound(a, a + n, k) - a));
	}
	return 0;
}

E - White and Black Balls

题目大意

有多少种排列 N N N个白球和 M M M个黑球的方法使得下列条件成立?

  • 对于每个 i i i ( 1 ≤ i ≤ N + M 1\le i\le N+M 1iN+M),设 w i w_i wi b i b_i bi分别是最左边 i i i个球中白球和黑球的数量, w i ≤ b i + K w_i\le b_i+K wibi+K成立。

答案对 ( 1 0 9 + 7 ) (10^9+7) (109+7)取模。

0 ≤ N , M ≤ 1 0 6 0\le N,M\le10^6 0N,M106
1 ≤ N + M 1\le N+M 1N+M
0 ≤ K ≤ N 0\le K\le N 0KN

输入格式

N   M   K N~M~K N M K

输出格式

输出答案,对 ( 1 0 9 + 7 ) (10^9+7) (109+7)取模。

样例

N N N M M M K K K输出
2 2 2 3 3 3 1 1 1 9 9 9
1 1 1 0 0 0 0 0 0 0 0 0
1000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000 1000000 192151600 192151600 192151600

分析

首先,本题中合法排列数就是如下符合任意 y ≤ x + K y\le x+K yx+K ( 0 , 0 ) → ( M , N ) (0,0)\to(M,N) (0,0)(M,N)最短路径的数量:
路径解释图
由此可见,如果 N > M + K N>M+K N>M+K(即终点超出限制),答案一定为 0 0 0
我们还可以发现,如果没有 y ≤ x + K y\le x+K yx+K这个限制,答案为 ( N + M N ) \binom{N + M}{N} (NN+M)
我们再考虑不合法的路径数,数量为 ( N + M M + K + 1 ) \binom{N + M}{M + K + 1} (M+K+1N+M)
因此,答案为 ( N + M N ) − ( N + M M + K + 1 ) \binom{N + M}{N}-\binom{N + M}{M + K + 1} (NN+M)(M+K+1N+M)

代码

这里用AtCoder Library好像比较方便唉~

#include <iostream>
#include <atcoder/modint>
using namespace std;

using modint = atcoder::modint1000000007;

modint f(int n, int m)
{
	if(n < 0 || m < 0)
		return 0;
	modint ret = 1;
	for(int i=1; i<=m; i++)
		ret = ret * (n + i) / i;
	return ret;
}

int main()
{
	int n, m, k;
	scanf("%d%d%d", &n, &m, &k);
	if(n > m + k) puts("0");
	else printf("%d\n", (f(n, m) - f(n - k - 1, m + k + 1)).val());
	return 0;
}
AtCoder Beginner Contest 134 是一场 AtCoder 的入门级比赛,以下是每道题的简要题解: A - Dodecagon 题目描述:已知一个正十二边形的边长,求它的面积。 解题思路:正十二边形的内角为 $150^\circ$,因此可以将正十二边形拆分为 12 个等腰三角形,通过三角形面积公式计算面积即可。 B - Golden Apple 题目描述:有 $N$ 个苹果和 $D$ 个盘子,每个盘子最多可以装下 $2D+1$ 个苹果,求最少需要多少个盘子才能装下所有的苹果。 解题思路:每个盘子最多可以装下 $2D+1$ 个苹果,因此可以将苹果平均分配到每个盘子中,可以得到最少需要 $\lceil \frac{N}{2D+1} \rceil$ 个盘子。 C - Exception Handling 题目描述:给定一个长度为 $N$ 的整数序列 $a$,求除了第 $i$ 个数以外的最大值。 解题思路:可以使用两个变量 $m_1$ 和 $m_2$ 分别记录最大值和次大值。遍历整个序列,当当前数不是第 $i$ 个数时,更新最大值和次大值。因此,最后的结果应该是 $m_1$ 或 $m_2$ 中较小的一个。 D - Preparing Boxes 题目描述:有 $N$ 个盒子和 $M$ 个物品,第 $i$ 个盒子可以放入 $a_i$ 个物品,每个物品只能放在一个盒子中。现在需要将所有的物品放入盒子中,每次操作可以将一个盒子内的物品全部取出并分配到其他盒子中,求最少需要多少次操作才能完成任务。 解题思路:首先可以计算出所有盒子中物品的总数 $S$,然后判断是否存在一个盒子的物品数量大于 $\lceil \frac{S}{2} \rceil$,如果存在,则无法完成任务。否则,可以用贪心的思想,每次从物品数量最多的盒子中取出一个物品,放入物品数量最少的盒子中。因为每次操作都会使得物品数量最多的盒子的物品数量减少,而物品数量最少的盒子的物品数量不变或增加,因此这种贪心策略可以保证最少需要的操作次数最小。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值