牛客2021年多校训练营<1>

本文介绍了几个编程题目,涉及动态规划、几何计算、图像处理和数组操作。 Alice 和 Bob 的石头游戏使用 SG 函数实现动态规划求解;球下落问题通过比较半径与底边长度判断;确定照片位置计算覆盖区域;交换数字游戏中利用数组前缀和求解最大值;水管道逃生问题未提供解题思路。
摘要由CSDN通过智能技术生成

Alice and Bob

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述 :

Alice and Bob like playing games. There are two piles of stones with numbers {n}n and {m}m. Alice and Bob take turns to operate, each operation can take away {k}(k>0)k(k>0) stones from one pile and take away s \times k(s \geq 0)s×k(s≥0) stones from another pile. Alice plays first. The person who cannot perform the operation loses the game.

Please determine who will win the game if both Alice and Bob play the game optimally.

输入描述:

The first line contains an integer T(1 \le T \le 10^4)T(1≤T≤10
4
) denotes the total number of test cases.
Each test case contains two integers n,m(1 \le n,m \leq 5 \times 10^3)n,m(1≤n,m≤5×10
3
) in a line, indicating the number of two piles of stones.

输出描述:

For each test case, print “Alice” if Alice will win the game, otherwise print “Bob”.

示例1
输入

5
2 3
3 5
5 7
7 5
7 7

输出

Bob
Alice
Bob
Bob
Alice

思路:

SG函数:
从(0,0)开始递推,由于(0,0)是必输态,则一部可达(0,0)的都是必胜态,不断更新sg[m][n]函数,直到m,n=5000为止,此时,只需查询sg函数中值即可。

代码:

#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <iomanip>
using namespace std;
typedef  long double ld;
typedef  long long ll;
const int maxn = 5005;
bool sg[maxn][maxn];

int main() {

	for (int i = 0; i < maxn; i++) {
		for (int j = 0; j < maxn; j++) {
			if (!sg[i][j]) {//后手必赢情况
				for (int k = 1; k + i < maxn; k++) {
					for (int s = 0; s * k + j < maxn; s++) {
						sg[k + i][s * k + j] = 1;
					}
				}
				for (int k = 1; k + j < maxn; k++) {
					for (int s = 0; s * k + i < maxn; s++) {
						sg[s * k + i][k + j] = 1;
					}
				}
			}
		}
	}
	int t;
	cin >> t;
	while (t--) {
		int m, n;
		scanf("%d %d", &n, &m);
		if (sg[n][m])  printf("Alice\n");
		else printf("Bob\n");
	}
	return 0;
}

ps.scanf和printf是好东西,cin,cout加了解绑也会爆时间就离谱好吧。。。。。。

Ball Dropping

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld

题目描述

A standard sphere ball is falling in the air, and the center of the sphere is exactly on the centerline of an empty isosceles trapezoidal. The trapezoid is hanging horizontally under the sphere.

Please determine whether the ball will get stuck in the trapezoid or drop past the trapezoid.

输入描述:

The input contains four integers r, a, b, h(1 \le r,a,b,h \le 1000, a > b)r,a,b,h(1≤r,a,b,h≤1000,a>b), indicating the radius of the ball, the top base, the bottom base, and the height of the isosceles trapezoid.

输出描述:

Output ‘Drop’ if the sphere ball will drop past the empty trapezoid, otherwise output ‘Stuck’.
If the answer is ‘Stuck’, please also calculate the stuck position(the height between the center of the sphere and the midpoint of the bottom base). Your answer is considered correct if its absolute or relative error does not exceed 10^−6

思路:

2*r与b相比,大于会卡住,小于落下,卡住时推公式求解

代码

#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <iomanip>
using namespace std;
typedef  long double ld;


int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	ld r, a, b, h;
	cin >> r >> a >> b >> h;
	if (2 * r >= b) {
		cout << "Stuck" << endl; ld ll;
		ll = h * h + (a - b) * (a - b) / 4;
		ll = pow(ll, 0.5);
		ld x = (b * h - 2 * ll * r) / (b - a);
		cout << fixed << setprecision(9) << x << endl;
	}
	else {
		cout << "Drop" << endl;
	}
	return 0;
}

Determine the Photo Position

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述 :

You have taken the graduation picture of graduates. The picture could be regarded as a matrix A of n \times nn×n, each element in A is 0 or 1, representing a blank background or a student, respectively.

However, teachers are too busy to take photos with students and only took a group photo themselves. The photo could be regarded as a matrix B of 1 \times m1×m where each element is 2 representing a teacher.

As a master of photoshop, your job is to put photo B into photo A with the following constraints:
you are not allowed to split, rotate or scale the picture, but only translation.
each element in matrix B should overlap with an element in A completely, and each teacher should overlap with a blank background, not shelter from a student.

Please calculate the possible ways that you can put photo B into photo A.
.

输入描述:

The first line contains two integers n,m(1 \le n,m \le 2000)n,m(1≤n,m≤2000) indicating the size of photos A and B.

In the next n n n lines,each line contains {n}n characters of ‘0’ or ‘1’,representing the matrix A.

The last line contains {m}m characters of ‘2’, representing matrix B.

输出描述:

在这里插入图片描述

Output one integer in a line, indicating the answer.
在这里插入图片描述

在这里插入图片描述
思路:就普遍理性而言,维护个前缀和在插一遍就行了
代码

#include<iostream>
#include<vector>
#include<string>
using namespace std;

int n, m;
vector<int> B;
vector<vector<int> > A;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	A.resize(n + 1);
	B.resize(m + 1);
	for (int i = 0; i <= n; ++i)
	{
		A[i].resize(n + 1);
	}
	for (int i = 1; i <= n; ++i)
	{
		string tmp;
		cin >> tmp;
		tmp = '0' + tmp;
		for (int j = 1; j <= n; ++j)
		{
			A[i][j] = A[i][j - 1] + tmp[j] - '0';
		}
	}
	string tmp;
	cin >> tmp;
	int ans = 0;
	for (int i = 1; i <= n; ++i)
	{
		for (int j = m; j <= n; ++j)
		{
			if (A[i][j] - A[i][j - m] == 0)
			{
				++ans;
			}
		}
	}
	cout << ans << endl;
	return 0;
}

Game of Swapping Numbers

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
在这里插入图片描述

输入描述:

在这里插入图片描述

输出描述:

Output one integer, the maximum answer.

样例:

在这里插入图片描述

思路:

赋予同等的±号,使得数组间差的绝对值最大,通过推导可得,最优的解比原解大
在这里插入图片描述
根据引理有n>2时,操作k次和操作不超过k次等价,再将那么根据引理,将所有 min数组和max数组分别从小到大、从大到小 sort 一遍,从前往后扫一遍,当后者大于前者时就将贡献加上,这样做能够使贡献最大化。

代码:

#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef long double ld;
const int N = 500005;
ll a[N];
ll b[N];
ll mi[N];
ll ma[N];


int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int n, k;
	ll sum = 0;
	cin >> n >> k;
	if (n == 2) {
		for (int i = 0; i < n; i++) {
			cin >> a[i];
		}
		for (int i = 0; i < n; i++) {
			cin >> b[i];
		}
		if (k & 1)swap(a[0], a[1]);
		sum = abs(a[0] - b[0]) + abs(a[1]- b[1]);
		cout << sum;
		return 0;
	}
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	for (int i = 0; i < n; i++) {
		cin >> b[i];
	}

	for (int i = 0; i < n; i++) {
		sum = sum + abs(a[i] - b[i]);
	}
	for (int i = 0; i < n; i++) {
		mi[i] = min(a[i], b[i]);
		ma[i] = max(a[i], b[i]);
	}
	sort(mi, mi + n);
	sort(ma, ma + n);
	for (int i = 0; i < n && i < k; i++) {
		if (mi[n - i - 1] > ma[i]) {
			sum += 2 * (mi[n - i - 1] - ma[i]);
		}
		else {
			break;
		}
	}
	cout << sum << endl;
	return 0;
}

Escape along Water Pipe

时间限制:C/C++ 3秒,其他语言6秒
空间限制:C/C++ 524288K,其他语言1048576K
Special Judge, 64bit IO Format: %lld

题目描述:

You’re trapped into a map with n \times mn×m grids, each grid has a strange water pipe.

There are six types of water pipes, denote them as ID 0,1,\dots,50,1,…,5.

You are located at the top of grid {(1,1)}(1,1) and you want to reach the bottom of grid {(n,m)}(n,m). In each step, you should travel along the pipe and move to another grid.
在这里插入图片描述

Before each move, you can do beautiful magic once: pick one of the degrees from {{0, 90, 180, 270}}{0,90,180,270}, select any number of grids except the one you are located at, and rotate their water pipes with the same degree you pick in the clockwise direction. Note that after you step in a grid along the water pipe, you must walk along the other end of the pipe to leave this grid.

You may step in the same grid multiple times, and the direction can be different every time you enter.

Determine whether you can escape from the entrance to the exit successfully.

输入描述:

在这里插入图片描述

输出描述:

在这里插入图片描述
在这里插入图片描述

思路:

不会,先存着。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值