Codeforces Round #771 (Div. 2)---A-D

A. Reverse—思维

题意:
给一个1 ~ n全排列组成的数组,任意找一个左端点l和右端点r,将l ~ r区间的数反转一下,求得到字典序最小的新数组

#include 
#include 
#include 

using namespace std;
#define int long long

int a[510];
void solve()
{
	int n;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)cin>>a[i];
	int l=1,r=1;
	for(int i=1;i<=n;i++)
	{
		if(a[i]>i)
		{
			l=i;
			break;
		}
	}
	for(int i=1;i<=n;i++)
	{
		if(a[i]==l)
		{
			r=i;
			break;
		}
	}
	
	for(int i=1;i<l;i++)cout<<a[i]<<" ";
	for(int i=r;i>=l;i--)cout<<a[i]<<" ";
	for(int i=r+1;i<=n;i++)cout<<a[i]<<" ";
	cout<<endl;
}
signed main()
{
   int T;
   scanf("%lld",&T);
   while(T--)solve();
}

B. Odd Swap Sort—思维

题意:
给一组数,当相邻两个数之和为奇数时可以交换,问能否通过若干次操作,使原数组变为不降序列
思路:
奇偶性判断即可,如果前边出现比后边大的必须要交换到后边,但同为偶数或者同为奇数,则不能交换,所以把数组分为奇数和偶数序列,如果奇数和偶数都不降则满足要求

#include 
#include 
#include 
using namespace std;
#define int long long
const int N = 100010;

int a[N];
void solve()
{
	int n;
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)scanf("%lld",a+i);
	bool f=true;
	
	int maxv1=0,maxv2=0;
	for(int i=1;i<=n;i++)
	{
		if(a[i]&1)
		{
			if(maxv1>a[i])
			{
				f=false;
				break;
			}
			maxv1=a[i];
		}
		else
		{
			if(maxv2>a[i])
			{
				f=false;
				break;
			}
			maxv2=a[i];
		}
	}
	
	if(f)cout<<"Yes"<<endl;
	else cout<<"No"<<endl;
}
signed main()
{
   int T;
   scanf("%lld",&T);
   while(T--)solve();
}

C. Inversion Graph—贪心

题意:
一个由1~n全排列组成的数组p
如果满足 i < j 且 p i > p j i < j 且pi > pj i<jpi>pj则i和j连一条边,问最后有几个连通块
思路:
很容易找到一个性质:
如果一个数前边有比它大的数则一定在那个大的数的连通块里
又因为是全排列,我们直接遍历就行了

#include 
#include 
#include 

using namespace std;
const int N = 100010;

int a[N];
int n;
void solve()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",a+i);
	int res=0;
	int maxv=0;
	for(int i=1;i<=n;i++)
	{
		if(maxv<i)res++;
		maxv=max(maxv,a[i]);
	}
	cout<<res<<endl;
}
signed main()
{
   int T;
   scanf("%d",&T);
   while(T--)solve();
}

D. Big Brush—bfs

思路很简单关键是实现

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef pair<int, int> PII;
const int N = 100010;
void solve()
{
	int n,m;
	cin>>n>>m;
	vector<vector<int>>a(n+1);
	for(int i=1;i<=n;i++)
	{
	 	a[i].resize(m+1);
	 	for(int j=1;j<=m;j++)cin>>a[i][j];
	}
	auto equal = [&](int x,int y)
	{
	 	int col=0;
	 	if(x<=0||x>=n||y<=0||y>=m)return make_pair(false,col);
	 	set<int>s;
	 	for(auto it:{a[x][y],a[x+1][y],a[x][y+1],a[x+1][y+1]})
	 		if(it!=-1)s.insert(it),col=it;
	 		return make_pair(s.size()==1,col);
	};
	
	auto paint = [&](int x,int y,int col)
	{
		a[x][y]=a[x+1][y]=a[x][y+1]=a[x+1][y+1]=col;
	};
	
	queue<tuple<int,int,int>>q;
	vector<tuple<int,int,int>>path;
	
	for(int i=1;i<n;i++)
		for(int j=1;j<m;j++)
		{
			auto [res,col] = equal(i,j);
			if(res)
			{
				q.push({i,j,col});
				path.push_back({i,j,col});
				paint(i,j,-1);
			}
		}
	while(q.size())
	{
		auto [x,y,val] = q.front();
		q.pop();
		for(int i=x-1;i<=x+1;i++)
			for(int j=y-1;j<=y+1;j++)
			{
				auto [res,col] = equal(i,j);
				if(res)
				{
					q.push({i,j,col});
					paint(i,j,-1);
					path.push_back({i,j,col});
				}
			}
	}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(a[i][j]!=-1)
			{
				cout<<-1<<'\n';
				return ;
			}
	reverse(path.begin(),path.end());
	cout<<path.size()<<'\n';
	for(auto [x,y,col] : path)
		cout<<x<<" "<<y<<" "<<col<<'\n';
}
signed main()
{
   int T;
   T=1;
   while(T--)solve();
}

你可能感兴趣的:(比赛补题,c++,c语言,算法)