AtCoder Beginner Contest 171 A~D 题解

A - αlphabet

题目大意

输入一个英文字母$a$,判断它是大写还是小写。

输入格式

$a$

输出格式

如果$a$为小写,输出a
如果$a$为大写,输出A

样例输入1

1
B

样例输出1

1
A

B为大写,所以输出A

样例输入2

1
a

样例输出2

1
a

a为小写,所以输出a

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include <cstdio>
using namespace std;

int main(int argc, char** argv)
{
	char a = getchar();
	if('a' <= a && a <= 'z') putchar('a');
	else putchar('A');
	return 0;
}

B - Mix Juice

题目大意

给定一个长度为$N$的数组$p_1, p_2, p_3, ..., p_N$,要求从其中选出$K$个数,使它们的和最小。

$1\le K\le N\le 1000$
$1\le p_i\le 1000$ ($1\le i\le N$)

输入格式

$N K$
$p_1~p_2~p_3~\dots~p_N$

输出格式

一行,即最小的和。

样例输入1

1
2
5 3
50 100 80 120 80

最小的和是$50+80+80=210$。

样例输出1

1
210

B为大写,所以输出A

样例输入2

1
2
1 1
1000

样例输出2

1
1000

因为只有一个数,所以最小的和就是$1000$。(此注释为笔者所加)

代码

题目要求和最小,其实只要找到数组中最小的$K$个数字的和即可。可以使用<algorithm>库中的sort()函数对p数组进行升序排序,再取前$K$个数字之和作为结果输出。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <cstdio>
#include <algorithm>
#define maxn 1005
using namespace std;

int a[maxn];

int main(int argc, char** argv)
{
	int n, k, sum = 0;
	scanf("%d%d", &n, &k);
	for(int i=0; i<n; i++)
		scanf("%d", a + i);
	sort(a, a + n);
	for(int i=0; i<k; i++)
		sum += a[i];
	printf("%d\n", sum);
	return 0;
}

C - One Quadrillion and One Dalmatians

题目大意

有$1000000000000001$($10^{15}+1$)只狗,它们的名字分别为:
a, b, .., z, aa, ab, .., az, ba, bb, .., bz, .., za, zb, .., zz, aaa, aab, .., aaz, aba, abb, .., abz, ., zzz, aaaa, ..
问题:第$N$只狗的名字是什么?

$1\le N\le 10^{15}+1$

输入格式

$N$

输出格式

一行,即第$N$只狗的名字。

样例

样例较多,为了节省文章篇幅,所以直接整合成表格:

输入 输出
2 b
27 aa
123456789 jjddja

代码

其实就是把十进制转换成二十六进制:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <cstdio>
#define BASE 26LL
using namespace std;

int main(int argc, char** argv)
{
	char s[12];
	int cnt = 0;
	long long n;
	scanf("%lld", &n);
	while(n > 0)
	{
		n --;
		s[cnt++] = n % BASE + 'a';
		n /= BASE;
	}
	for(int i=cnt-1; i>=0; i--) putchar(s[i]);
	putchar('\n');
	return 0;
}

D - Replacing

题目大意

有一个数组$A_1, A_2, \dots, A_N$。
执行如下$Q$个操作:

  • 在第$i$个操作中,将数组中所有的$B_i$替换成$C_i$。
  • 输出操作后$A$中所有数之和(记为$S_i$)。

$1\le N, Q, A_i, B_i, C_i\le 10^5$ ($1\le i\le N$)
$B_i\ne C_i$

输入格式

$N$
$A_1~A_2~...~A_N$
$Q$
$B_1~C_1$
$B_2~C_2$
$:$
$B_Q~C_Q$

输出格式

$S_1$
$S_2$
$:$
$S_N$

样例输入1

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

样例输出1

1
2
3
11
12
16
时间 数组$A$
开始 $\{1, 2, 3, 4\}$
$i=1$ $\{2, 2, 3, 4\}$
$i=2$ $\{2, 2, 4, 4\}$
$i=3$ $\{4, 4, 4, 4\}$

样例输入2

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

注意:$B_i$不一定存在列表中。

样例输出2

1
2
3
8
4
4

样例输入3

1
2
3
4
5
6
2
1 2
3
1 100
2 100
100 1000

样例输出3

1
2
3
102
200
2000

代码

可以用数组记录$A$中每个值出现的次数。这里由于题目原因,还需要记录数组$A$每个数之和。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <cstdio>
#define maxn 100005
using namespace std;

typedef long long LL;

int cnt[maxn];
LL sum = 0;

inline LL s(const LL& i)
{
	return cnt[i] * i;
}

int main(int argc, char** argv)
{
	int n, q;
	scanf("%d", &n);
	for(int i=0; i<n; i++)
	{
		int t;
		scanf("%d", &t);
		sum += t;
		cnt[t] ++;
	}
	scanf("%d", &q);
	while(q--)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		sum -= s(x) + s(y);
		cnt[y] += cnt[x];
		cnt[x] = 0;
		sum += s(y);
		printf("%lld\n", sum);
	}
	return 0;
}
使用 Hugo 构建
主题 StackJimmy 设计