Educational Codeforces Round 134 (Rated for Div. 2)

比赛链接

A

题意:

给定4个字符串,每次可以将一种字符串变成另一个字符串,请求最少的操作使得所有字符串相同。

核心思路:就是一个找规律的题目,哈哈哈,看多了jly的代码还是有好处的。但是需要注意memset的用法,我在题目的时候就memset(vis,0, sizeof 0),犯病了。

#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N = 1e3 + 10;
unordered_map<int, int> mp;
int a[N], b[N];
int n;
char s[N][N];
int vis[N];
int erfen(int x)
{
	int l = 0;
	int r = n - 1;
	while (l < r)
	{
		int mid = l + r >> 1;
		if (b[mid] >= x)
			r = mid;
		else
			l = mid + 1;
	}
	return l;
}
void solve()
{
	int ans = 3;
	for (int i = 0;i < 2;i++)
		for (int j = 0;j < 2;j++)
			cin >> s[i][j];
	memset(vis, 0, sizeof vis);
	for (int i = 0;i < 2;i++)
		for (int j = 0;j < 2;j++)
		{
			if (!vis[s[i][j]])
			{
				vis[s[i][j]] = 1;
			}
			else
				ans--;
		}
	cout << ans << endl;

}
int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		solve();
	}
}

B

题意:

给定一个大小为n * m的棋盘,和一个特殊点[sx,sy]以及参数d。机器人从1,1出发到n,m,途中距离特殊点的曼哈顿距离不能小于等于d,否则就会被这个点蒸发,求机器人到n,m的最短路。

核心思路:这个的话还是需要画点图的,以那个激光点画一个十字图形就明白了。

#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
unordered_map<int, int> mp;
int a[N], b[N];
int n;
int erfen(int x)
{
	int l = 0;
	int r = n - 1;
	while (l < r)
	{
		int mid = l + r >> 1;
		if (b[mid] >= x)
			r = mid;
		else
			l = mid + 1;
	}
	return l;
}
void solve()
{
	int n, m, x, y, d;
	cin >> n >> m >> x >> y >> d;
	if ((y - d <= 1 || x + d >= n) && (y + d >= m || x - d <= 1))
	{
		cout << -1 << endl;
		return;
	}
	else
	{
		cout << n + m - 2<<endl;
	}
}
int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		solve();
	}
}

C

题意:

有一个不下降数组a,你构造由任意正整数构成的c数组,使得b[i] = a[i] + c[i],再将b数组排序。已知a数组和b数组,求出对于每一位i能够加上的最大和最小的c[i]。

核心思路:首先我们得注意一个特殊点,我们在求\(d_{max}\)的时候不可以直接和最大值和最小值进行比较。下面对照样例理解一下。先看样例1:

2 3 5
7 11 14

这个我们可以发现a数组的任何数字都可以变成b数组的任意数,所以直接取b数组的最大值和最小值就好了。但是我们改变下样例呢:

2 3 11
7 11 13

这种情况下11只能变为11 13,但是3却可以变为数组中的任意一个数。2也是可以的,所以这就产生了限制条件。所以我们可以发现a数组只能变为比它大的要不然d数组中就含有负数,但是题目居然给出了,那就说明肯定是有解的。

然后在更改下样例:

2 3 13 
7 11 13

这哥时候我们会发现13只能变为13,所以后面的2,3就少了一个变换的范围了。从这个例子我们也可以发现我们可以从后往前递推。因为这两个数组本身也是递增的所以我们可以慢慢地缩小范围。也就是找到每一个数的变化区间,然后使用最大值和最小值计算下就好了。

#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N = 3e5 + 10;
int n, m;
int ans[N][2];
int a[N], b[N];
int erfen(int x)
{
	int l = 0;
	int r = n - 1;
	while (l < r)
	{
		int mid = l + r >> 1;
		if (b[mid] >= x)
			r = mid;
		else
			l = mid + 1;
	}
	return l;
}
void solve()
{
    cin >> n;
    for (int i = 0; i < n; i++) cin >> a[i];
    for (int i = 0; i < n; i++) cin >> b[i];

    int top = n-1;
    for (int i = n-1; i >= 0; i--)
    {
        int t = erfen(a[i]);//先找出第一个大于a[i]的值
        if (t == i)//t==i说明i到n个位置已经确定好d了,需要把上确界也更新一下.
        {
            //cout << top << " " << t << " " << i << endl;
            ans[i][0] = b[t] - a[i];
            ans[i][1] = b[top] - a[i];
            top = i - 1;
        }
        else
        {
            // cout << top << " " << t << " " << i << endl;
            ans[i][0] = b[t] - a[i];
            ans[i][1] = b[top] - a[i];
        }
    }

    for (int i = 0; i < n; i++) cout << ans[i][0] << " "; cout << endl;
    for (int i = 0; i < n; i++) cout << ans[i][1] << " "; cout << endl;
}
int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        solve();
    }
}

D

题意:

给定长度为n的数组a和数组b,可以随意构造b的顺序,使得数组c[i] = a[i] ^ b[i],请最大化c[1] & c[2] & ... c[n]的值。

核心思路:这里我们可以发现其实一个内在的规律就是找a[i]和b[i]中的0,1使之与之组合。因为这样才可以使得这个值是最大的,所以我们可以先把某一个位置j中的0,1全都挑选出来。其中j表示的是我们当前枚举的位数,然后再判断这个情况是不是合法的,也就是判断这个位置上面a中1的是不是等于b中的0.一定要注意我们统计的是某个位置而不是全部

#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
unordered_map<int, int> mp;
LL a[N], b[N];
void solve()
{
	int n;
	cin >> n;
	for (int i = 1;i <= n;i++)
		cin >> a[i];
	for (int i = 1;i <= n;i++)
		cin >> b[i];	
	LL ans = 0;
	for (int j = 30;j >= 0;j--)
	{
		ans |= 1 << j;
		map<int, int> mpa, mpb;
		for (int i = 1;i <= n;i++)
			mpa[ans & a[i]]++, mpb[ans & b[i]]++;
		int flag = 1;
		for (int i = 1;i <= n;i++)
		{
			if (mpa[ans & a[i]] != mpb[ans ^ (ans & a[i])])
			{
				flag = 0;
				break;
			}
		}
		if (!flag)
			ans -= (1 << j);
	}
	cout << ans << endl;
}
int main()
{
	int T;
	cin >> T;
	while (T--)
	{
		solve();
	}
}

小总结:代码方面不需要太死板其他博主的,主要是仿照思路就好了,然后就是看不懂的注意打量两组数据看下

posted @ 2022-12-08 23:12  努力的德华  阅读(40)  评论(0)    收藏  举报