Codeforces Round 896(Div.2)

A.Make It  Zero

题目链接:Problem - A - Codeforces

主要题意: 给定一串数字,通过异或运算可以使区间[l,r]变成相同的数,求最少使全串变成0的修改次数与l,r取值。

思路:其实这道题思路很简单:相同的数异或为0 

我们可以知道:如果区间所取数量为偶数时,通过一次异或可以变成相同数,再进行一次异或就可以全部变成0;如果区间为奇数时,我们可以取n-1进行2次异或为全0,再将一个0与后奇数部分结合,再进行两次就能全为0了!

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 105;
int a[N];
int n;
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		cin >> n;
		int sum = 0;
		memset(a, 0, sizeof(a));
		for (int i = 1; i <= n; i++)
		{
			cin >> a[i];
			sum ^= a[i];
		}
		if (sum == 0)
		{
			cout << 1 << endl;
			cout << 1 << " " << n << endl;
			continue;
		}
		if (n % 2 == 0)
		{
			cout << 2 << endl;
			cout << 1 << " " << n << endl;
			cout << 1 << " " << n << endl;
		}
		else
		{
			cout << 4 << endl;
			cout << 1 << " " << n - 1 << endl;
			cout << 1 << " " << n - 1 << endl;
			cout << n - 1 << " " << n << endl;
			cout << n - 1 << " " << n << endl;
		}
	}
	return 0;
}

B.2D Traveling

链接:Problem - B - Codeforces

题目大意:度假出行,n个城市,前k个是主要城市,主要城市之间出行不花钱,其余为非主要城市,非主要城市和主要城市之间出行要花费一定钱(曼哈顿距离),非与非之间也是如此,求从a城到b城最小花费!

思路:刚开始一看最短距离,想到Dij,但发现非与主或非与非之间的花费是曼哈顿距离,直接就是最优,就不需要搜索了,直接枚举考虑a,b分布情况。

(1). a,b都是主要城市,花费直接为0,输出

(2). a,b都不是主要城市,先求出a,b之间的花费ans,再求从主要城市到a,b各自的最少花费,相加后与ans进行比较,取最小值

(3)a,b有一个是主要城市,a到b与b到a是一样的,所以我们可以假定a<b,即a是主要城市,b是非主要,

这里可以直接枚举从主要城市到b的最小花费,取最小值。

代码:
#include <bits/stdc++.h>
#define ll  long long
using namespace std;
const int N = 2e5 + 10;
int n, k, a, b;
struct node {
	ll x, y;
}Cy[N];
ll Dis(int l, int r)
{
	return (ll)abs(Cy[l].x - Cy[r].x) + (ll)abs(Cy[l].y - Cy[r].y);
}

int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		cin >> n >> k >> a >> b;
		for (int i = 1; i <= n; i++)
		{
			cin >> Cy[i].x >> Cy[i].y;
		}
		if (a <= k && b <= k)
		{
			cout << 0 << endl;
			continue;
		}
		if (a>k&&b>k)
		{
			ll ans = Dis(a, b);
			ll ma = 1e18, mb = 1e18;
			for (ll i = 1; i <= k; i++)
			{
				ma = min(ma, Dis(i, a));
				mb = min(mb, Dis(i, b));
			}
			cout << min(ans, ma + mb) << endl;
			continue;
		}
		if (a > b) swap(a, b);
		ll ans = 1e18;
		for (int i = 1; i <= k; i++) ans = min(ans, Dis(i, b));
		cout << ans << endl;
	}
	return 0;
}

C.Fill in the Matrix

题目链接:Problem - C - Codeforces

题目大意:就是给你矩阵的行数和列数,定义每一行的值[0,m-1]之间且不重复,使vi=MEX(i列中未出现的最小>=0整数),最后s=MEX(v组中未出现最小>=0整数),设计矩阵每行每列使s取到最大值!

思路:因为要是使s尽可能的大,所以我们希望每个vi也能做到不重复。如果我们假设v1=0,v2=1,v3=2...我们应该怎么实现呢? 其实很简单,我们可以假设第一行的数为1,2,3...m-1,0,

然后依次左移一位,我们可以发现就可以构造出上面那个V序列,但是需要注意的是我们左移的次数是有限制的,因为过多的移动会使每个数在一列中都能出现,此时就无法得到最大答案,只能得0。次数其实很好判断,num=min(n,m-1),不多赘述(移一移就知道了),然后我们用第一行去覆盖未赋值的行数,就能实现了。M=1是一个特例要分出来解,记得不要忘了这个也要输出矩阵(zzz赛时没输wa了两次OVO)!

代码:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int n, m;
vector<int>a[200010];
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		cin >> n >> m;
		for (int i = 0; i<m; i++)
		{
			a[1].push_back(i);
		}
		for (int i = 2; i <= min(m - 1, n); i++)
		{
			for (int j = 0; j < m; j++)
			{
				a[i].push_back(a[i - 1][(j + 1) % m]);
			}
		}
		for (int i = min(m - 1, n) + 1; i <= n; i++)
		{
			a[i] = a[1];
		}
		if (m == 1)
		{
			cout << 0 << endl;
			for (int i = 1; i <= n; i++) cout<<0<< endl;
			for (int i = 1; i <= n;i++) a[i].clear();
			continue;
		}
		else
		{
			cout << min(m,n + 1) << endl;
			for (int i = 1; i <= n; i++)
			{
				for (int j = 0; j < m; j++)
				{
					if (j == m - 1) cout << a[i][j];
					else cout << a[i][j] << " ";
				}
				cout << endl;
			}
			for (int i = 1; i <= n; i++) a[i].clear();
		}
	}
	return 0;
}

比赛做了一个小时就润了,目前就先更A,B,C吧

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值