Codeforces Round #753 (Div. 3) (A~E)

A. Linear Keyboard

题目大意

第一行给你一个长度为26的字符串,代表26个字母的排列循序,相邻字母的距离为 1 。
第二行给你一个字符串,问从头走到尾共走了多长的距离。

解题思路

暴力枚举即可。

AC代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int t; scanf("%d", &t);
	while (t--)
	{
		string s1, s2; 
		cin >> s1 >> s2;
		int ans = 0;
		for (int i = 1; i < s2.size(); i++)
		{
			int k = s1.find(s2[i]) - s1.find(s2[i - 1]);
			ans += abs(k);
		}
		cout << ans << endl;
	}
	return 0;
}

B. Odd Grasshopper

题目大意

给你一个起始坐标 x ,给你一个跳跃的次数 n 。第 i 次跳跃的长度为 i。然后跳跃的方向取决于跳跃位置的奇偶性,偶数向左跳跃,奇数向右跳跃,问最后的位置。

解题思路

对 x 的奇偶性分类讨论,找规律。

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int main()
{
	int t; scanf("%d", &t);
	while (t--)
	{
		ll x, n; scanf("%lld%lld", &x, &n);
		ll ans;
		if (x % 2 == 0)
		{
			if (n % 4 == 0) ans = x;
			if (n % 4 == 1) ans = x - n;
			if (n % 4 == 2) ans = x + 1;
			if (n % 4 == 3)ans = n + 1 + x;
		}
		else
		{
			if (n % 4 == 0) ans = x;
			if (n % 4 == 1) ans = x + n;
			if (n % 4 == 2) ans = x - 1;
			if (n % 4 == 3) ans = x - 1 - n;
		}
		cout << ans << endl;
	}
	return 0;
}

C. Minimum Extraction

题目大意

给你一个长度为n的数组,每次从数组中找到最小的元素 x ,然后删除该元素,并将剩余元素都 - x,直到数组的长度为1。求每次变化后数组中最小元素的最大值。

解题思路

设一个排好序的数组:A1 A2 A3 A4 A5 。
第一步操作:A1 A2 A3 A4 A5
第二步操作:A2-A1 A3-A1 A4-A1 A5-A1
第三步操作:A3-A2 A4-A2 A5-A2
第四步操作:A4-A3 A5-A3
第五步操作:A5-A4
综上:答案为 max(A1, A2-A1, A3-A2, A4-A3, A5-A4)

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int n;
int a[N];
int main()
{
	int t; scanf("%d", &t);
	while (t--)
	{
		scanf("%d", &n);
		for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
		sort(a + 1, a + 1 + n);
		int mx = a[1];
		for (int i = 1; i <= n; i++) mx = max(mx, a[i] - a[i - 1]);
		printf("%d\n", mx);
	}
	return 0;
}

D. Blue-Red Permutation

题目大意

给你一个长度为n的数组,然后再给你一个长度为n的字符串,字符串由‘B’和‘R’组成,数组中每一个元素与字符串想对应,若对应的字符为‘B’,代表该元素每次可以减少1,反之若对应‘R’,代表该元素每次可以增加1,次数不限。问是否可以将该数组变成1~n的排列。

解题思路

这是一道贪心的题目。
设蓝色元素的个数为len1,红色元素的个数为len2.
判断所有蓝色元素是否能组成1~len1,所有红色元素是否能组成len+1 ~ n。若不能则答案为NO,反之为YES。

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int a[N];
int main()
{
	int t; cin >> t;
	while (t--)
	{
		vector<int> blue, red;
		int n; scanf("%d", &n);
		for (int i = 0; i < n; i++) scanf("%d", &a[i]);
		string s; cin >> s;
		for (int i = 0; i < n; i++)
		{
			if (s[i] == 'B') blue.push_back(a[i]);
			else red.push_back(a[i]);
		}
		sort(blue.begin(), blue.end());
		sort(red.begin(), red.end(), greater<int>());
		bool bug = true;
		for (int i = 0; i < blue.size(); i++)
		{
			if (blue[i] <= i)
			{
				bug = false;
				break;
			}
		}
		for (int i = 0; i < red.size(); i++)
		{
			if (red[i] > n - i)
			{
				bug = false;
				break;
			}
		}
		puts(bug ? "YES" : "NO");
	}
	return 0;
}

E. Robot on the Board 1

题目大意

给你一个n * m 的网格,再给你一个字符串,代表机器人的行走路径,机器人不能走出网格,问机器人从那个位置开始走才能使行走的距离更长。

解题思路

暴力枚举即可,分别用四个变量mn1,mx1,mn2,mx2记录一下向左向右向上向下走的最远距离。当mx1-mn1+1>m或者mx2-mn2+1>n时跳出循环。

AC代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int t; cin >> t;
	while (t--)
	{
		int n, m; scanf("%d%d", &n, &m);
		string s; cin >> s;
		int mn1 = 0, mn2 = 0, mx1 = 0, mx2 = 0;
		int h = 0, l = 0;
		for (int i = 0; i < s.size(); i++)
		{
			if (s[i] == 'R') h++;
			if (s[i] == 'L') h--;
			if (s[i] == 'U') l++;
			if (s[i] == 'D') l--;
			mn1 = min(mn1, h);
			mx1 = max(mx1, h);
			mn2 = min(mn2, l);
			mx2 = max(mx2, l);
			if (mx1 - mn1 + 1 > m)
			{
				if (s[i] == 'R') mx1--;
				else mn1++;
				break;
			}
			if (mx2 - mn2 + 1 > n)
			{
				if (s[i] == 'U') mx2--;
				else mn2++;
				break;
			}
		}
		printf("%d %d\n", 1 + mx2, 1 - mn1);
	}
	return 0;
}
上一篇:CocosCreator无尽循环列表,长列表优化drawcall,scrollview列表优化


下一篇:努力学习,记录自己的每一次进步