19级暑假第三场训练赛

A题:

CodeForces - 1216A

题目描述

A01

A02

输入:

4
bbbb

输出

2
abba

思路:

简单模拟即可,做的时候想到了前缀,但即时反应过来了

#include <bits/stdc++.h>
using namespace std;
string s;
int n;
int main(){
	cin >> n >> s;
	int cnt = 0;
	for (int i = 0; i < n; i += 2){
		if (s[i] == s[i + 1]){
			++cnt;
			s[i] = 'b' - s[i + 1] + 'a';
		}
	}
	cout << cnt << endl << s << endl;
}

B题:

CodeForces - 1399B

B01

B02

Input

5
3
3 5 6
3 2 3
5
1 2 3 4 5
5 4 3 2 1
3
1 1 1
2 2 2
6
1 1000000000 1000000000 1000000000 1000000000 1000000000
1 1 1 1 1 1
3
10 12 8
7 5 4

Output

6
16
0
4999999995
7

Note

In the first test case of the example, we can perform the following sequence of moves:

  • choose the first gift and eat one orange from it, so a=[3,5,6]a=[3,5,6] and b=[2,2,3]b=[2,2,3];
  • choose the second gift and eat one candy from it, so a=[3,4,6]a=[3,4,6] and b=[2,2,3]b=[2,2,3];
  • choose the second gift and eat one candy from it, so a=[3,3,6]a=[3,3,6] and b=[2,2,3]b=[2,2,3];
  • choose the third gift and eat one candy and one orange from it, so a=[3,3,5]a=[3,3,5] and b=[2,2,2]b=[2,2,2];
  • choose the third gift and eat one candy from it, so a=[3,3,4]a=[3,3,4] and b=[2,2,2]b=[2,2,2];
  • choose the third gift and eat one candy from it, so a=[3,3,3]a=[3,3,3] and b=[2,2,2]b=[2,2,2].

题目大意:均分礼物,提供n个礼物,每个礼物由糖果,桔子组成,要求最后分配到每个人手上的糖数量相等,桔子数量相等。

思路:

每次可以这样操作,要么同一种礼物中的糖数量减少1,要么同一种礼物中的桔子数量减少1,要么同一种糖与桔子数量均较少1.

要求,算出最少操作次数。使第三种操作最多即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node {
	ll a, b;
}e[60];
int main() {
	//freopen("in.txt", "r", stdin);
	ios::sync_with_stdio(false), cin.tie(0);
	int n, t; cin >> t;
	while (t--) {
		cin >> n; ll mina = 0x3f3f3f3f, minb =  0x3f3f3f3f;
		for (int i = 1; i <= n; ++i) {
			cin >> e[i].a;
			mina = min(mina, e[i].a);
		}
		for (int i = 1; i <= n; ++i) {
			cin >> e[i].b;
			minb = min(minb, e[i].b);
		}
		ll cnt = 0;
		for (int i = 1; i <= n; ++i) {
			cnt += max(e[i].a - mina, e[i].b - minb);
		}
		cout << cnt << endl;
	}
}

C题:

CodeForces - 1216C

矩形桌上放着一张白纸。该工作表是一个矩形,其边平行于桌子的边。如果您从上方看一下,并假设表格的左下角具有坐标(0,0),并且坐标轴位于表格的左右两侧,则白板的左下角具有坐标( x1,y1),以及右上角的-(x2,y2)。 之后,将两张黑纸放在桌子上。两个黑纸的侧面也平行于桌子的侧面。第一个黑色工作表的左下角的坐标为(x3,y3),而右上角的坐标为(x4,y4)。第二个黑色工作表的左下角的坐标为(x5,y5),右上角的坐标为(x6,y6)。

三个矩形的示例

确定放置两张黑纸后,是否可以从上方看到白纸的某些部分。如果至少有一个点不严格位于白板内部,而并非严格位于两个黑色板外部,则可以看到白板的一部分。

Input

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

Output

NO

Input

3 3 7 5
0 0 4 6
0 0 7 4

Output

YES

Input

5 2 10 5
3 1 7 6
8 1 11 7

Output

YES

Input

0 0 1000000 1000000
0 0 499999 1000000
500000 0 1000000 1000000

Output

YES
#include<bits/stdc++.h>
using namespace std;
int main(){
    //freopen("in.txt", "r", stdin);
    int a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c4, c3;
    bool flag = true;
    cin >> a1 >> a2 >> a3 >> a4;
    cin >> b1 >> b2 >> b3 >> b4;
    cin >> c1 >> c2 >> c3 >> c4;
    if (b1 <= a1 && b2 <= a2 && b3 >= a3 && b4 >= a4) flag = 0;
    else {
        if (b1 <= a1 && b2 <= a2 && b3 >= a3) a2 = max(a2, b4);
        if (b1 <= a1 && b3 >= a3 && b4 >= a4) a4 = min(a4, b2);
        if (b1 <= a1 && b2 <= a2 && b4 >= a4) a1 = max(a1, b3);
        if (b3 >= a3 && b2 <= a2 && b4 >= a4) a3 = min(a3, b1);
    }
    if (c1 <= a1 && c2 <= a2 && c3 >= a3 && c4 >= a4) flag = 0;
    if (flag) cout << "YES" << endl;
    else cout << "NO" << endl;
}

D题:

CodeForces - 1216D

D01

Example1

Input

3
3 12 6

Output

5 3

Input

7
2 1000000000 4 6 8 4 2

Output

2999999987 2

思路:

直接可以看出是求差值(与最大值)的最大公约数

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
long long a[1000001], max1 = 0, b[1000001];
int main(){
    //freopen("in.txt", "r", stdin);
    ll n, s = 0, max2;
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i],max1 = max(max1, a[i]);
    for (int i = 1; i <= n; i++)
        b[i] = max1 - a[i], s += b[i];
    max2 = b[1];
    for (int i = 1; i <= n; i++){
        if (b[i] == 0) continue;
        max2 = gcd(b[i], max2);
    }
    cout << s / max2 << " " << max2 << endl;
}

E题:

CodeForces - 1216E1

E01

E02

Input

5
1
3
20
38
56

Output

1
2
5
2
0

Input

4
2132
506
999999999
1000000000

Output

8
2
9
8

思路:

首先这道题不能用字符串暴力做,容易爆内存

我们另一个变量 (i) 单独存储最次增加的后缀,ans存储本该增加的字符串长度。然后放在while里面让它循环增长。

#include<bits/stdc++.h>
using namespace std;
int main() {
	//freopen("in.txt", "r", stdin);
	ios::sync_with_stdio(false), cin.tie(0);
	int t, n, i; cin >> t;
	while (t--) {
		cin >> n;
		int ans = 0; i = 1;
		string s = "";
		while (1) {
			s += to_string(i++);
			if (s.length() + ans >= n)break;
			ans += s.length();
		}
		cout << s[n - 1 - ans] << endl;
	}
}
原文地址:https://www.cnblogs.com/RioTian/p/13470428.html