Codeforces Round 896 (Div. 2)

A. A - Make It Zero

题意:

给你一个n个数字的数组,你可以执行至多八次操作,每次操作可以选取一个l和r,将l到r间的所有数替换为原来l到r之间数的总异或和。我们的目的是在操作后使数组所有数都变成0,可以证明一定有解决方案,且无需输出最小解决方案。

分析:

看到异或 0 ,突然一瞬间就来感觉,想起来自己和自己异或得0,于是直接想到把l取1,r取n,取第一次之后所有的数都是被同一个总异或和替换掉,取第二次l=1.r=n时把所有数异或到一起,然后直接开始爆写,写完直接交了个wa1哈哈哈,原来时我没考虑奇数,因为 偶数个相同的数异或到最后都是0,奇数个数相同的书异或到最后时多一个的,再考虑就觉得要先搞掉一个,留下偶数个的再用那个方法。好嘛,这就有思路了,我先把前两个数操作一遍,变成两个0,再把第二个数到最后一个(这时候就是偶数个了)按前面的方式再操作一遍,就ok啦,ac

代码:

#include <stdlib.h>
#include <iostream>
#include<cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include<iomanip>
#include<queue>
#include<stack>
#define int  long long
#define endl '\n'

//cout << fixed << setprecision(2) << 3.1415 << endl;
using namespace std;
const int N1=2e6+10;
const int N2=2e4+10;

void solve()
{
	int n;
	cin>>n;
	int a[n+1];

	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	if(n%2==0)
	{
	cout<<2<<endl<<1<<' '<<n<<endl;
	cout<<1<<' '<<n<<endl;
	}
	else 
	{
		cout<<4<<endl<<1<<' '<<2<<endl;
		cout<<1<<' '<<2<<endl;
		cout<<2<<' '<<n<<endl;
		cout<<2<<' '<<n<<endl;
	}
}

signed main()
{
	//师出彩笔 
	cin.tie(nullptr)->sync_with_stdio(0);
	int turn=1;
	cin>>turn;
	while(turn--)
	{	
		solve();
	}
}

B. B - 2D Traveling

题意:

题目大概是说,一个人想用最低的机票价格从第A城旅行到第B城,题目输入告诉你总共有n个城,其中在前k个城市间飞行不需要钱,其他时候飞行则需要花费曼哈顿距离的钱(也就是x坐标的绝对差值和y坐标的绝对差值之和)

分析:

直接说我想到的正确的思路吧,因为免费城市之间是可以直接飞的,相当于传送,那么我们只需要找到距离a最近的免费城市和距离b最近的免费城市,比较这个最小的距离和 相对于ab间直接飞的距离,输出更小的那个即可

代码:

#include <stdlib.h>
#include <iostream>
#include<cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include<iomanip>
#include<queue>
#include<stack>
#define int  long long
#define endl '\n'

//cout << fixed << setprecision(2) << 3.1415 << endl;
using namespace std;

void solve()
{
	int n,k,a,b;
	cin>>n>>k>>a>>b;
	int x[n+1],y[n+1];
	int amin=1e12,bmin=1e12;
	for(int i=1;i<=n;i++)
	{
		cin>>x[i]>>y[i];

	}
	for(int i=1;i<=n;i++)
	{
		if(i<=k)
		{
				amin=min(amin,abs(x[i]-x[a])+abs(y[i]-y[a]));
				bmin=min(bmin,abs(x[i]-x[b])+abs(y[i]-y[b]));
		}
	}
	int zz=abs(x[a]-x[b])+abs(y[a]-y[b]);
	 cout<<min(zz,amin+bmin)<<endl;
}

signed main()
{
	//师出彩笔 
	cin.tie(nullptr)->sync_with_stdio(0);
	int turn=1;
	cin>>turn;
	while(turn--)
	{	
		solve();
	}
}

C. C - Fill in the Matrix

题意:

题目告诉我们n和m,需要我们构造一个矩阵,其中这个矩阵的每行都是0 - m-1的数的随机排列,对于每一列的数我们取他们的MEX(即最小的未出现的自然数),再对每列得到的MEX再合起来取个MEX,我们的目标是要使这个最后的MEX最大,我们需要输出最大MEX,再输出我们构造的矩阵

分析:

首先考虑几个特殊情况,当行数为1同时列数为1时,即1x1时,MEX为0,矩阵为0;当行数为1,列数大于1时,即1x几时,MEX为2,矩阵为一行的0 - m-1;当列数为1,行数大于1时,MEX为0,矩阵为一列的0 - m-1

再考虑其他情况,对于行数大于等于列数的可以这样考虑,最大MEX都为m,前m-1行都是有规律的变化,每次向前推一个顶到后面,后面多余的行都与第一行一样。

添加图片注释,不超过 140 字(可选)

对于行数小于列数的,最大MEX都为n+1,所有的行都是有规律的变化,每次向前推一个顶到后面

添加图片注释,不超过 140 字(可选)

关于证明有待读者自行发掘,思路历程有些复杂暂且不表

代码:

#include <stdlib.h>
#include <iostream>
#include<cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include<iomanip>
#include<queue>
#include<stack>
#define int  long long
#define endl '\n'

//cout << fixed << setprecision(2) << 3.1415 << endl;
using namespace std;

void solve()
{
	int n,m;
	cin>>n>>m;
	if(n==1&&m==1)
	{
		cout<<0<<endl<<0<<endl;
	}
	else if(n==1)
	{
		cout<<2<<endl;
		for(int i=0;i<m;i++)
		{
			cout<<i<<' ';
		}
		cout<<endl;
		
	}
	else if(m==1)
	{
		cout<<0<<endl;
		for(int i=0;i<n;i++)
		{
			cout<<0<<endl;
		}	
	}
	else if(n>=m)
	{
		int a[2*m];
		for(int i=0;i<m;i++)
		{
			a[i]=i;
		}
		for(int i=m;i<2*m;i++)
		{
			a[i]=i-m;
		}
		cout<<m<<endl;
		for(int i=0;i<n;i++)
		{
			if(i<m-1)
			{
			
				for(int j=0;j<m;j++)
				{
					cout<<a[j+i]<<' ';
				}
				cout<<endl;
			}
			else 
			{
				for(int j=0;j<m;j++)
				{
					cout<<j<<' ';
				}
				cout<<endl;
			}
		}
	}
	else if(n<m)
	{
		cout<<n+1<<endl;
		int a[2*m];
		for(int i=0;i<m;i++)
		{
			a[i]=i;
		}
		for(int i=m;i<2*m;i++)
		{
			a[i]=i-m;
		}
		for(int i=0;i<n;i++)
		{

			
				for(int j=0;j<m;j++)
				{
					cout<<a[j+i]<<' ';
				}
				cout<<endl;
			
		}
		
	}
}

signed main()
{
	//师出彩笔 
	cin.tie(nullptr)->sync_with_stdio(0);
	int turn=1;
	cin>>turn;
	while(turn--)
	{	
		solve();
	}
}

CSDN:陪你一起cf

bilibili:acmer--沈幼楚

知乎:与你cf

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值