Codeforces Global Round 9 ABCD

比赛连接:Codeforces Global Round 9 传送门

A - Sign Flipping

题意:可以随意改变a[i]的正负符号,要求至少有(n-1)/2个a[i]-a[i+1]≥0和至少有(n-1)/2个a[i]-a[i+1]≤0
题解:相邻两个数的正负符号不同

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int main()
{
    ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);
   int t;cin>>t;
   while(t--)
   {
       int n;cin>>n;
       vector<int>a(n,0);
       for(int i=0;i<n;i++)
       {
           cin>>a[i];
           a[i]=abs(a[i]);
       }
    	for(int i=0;i<n;i++)
    		if(i%2==0)
    		cout<<-a[i]<<" ";
    		else cout<<a[i]<<" ";
        cout<<endl;
   }
    return 0;
}

B - Neighbor Grid

题意:一个r行c列矩阵代表r行c列个人,a[i][j]表示第i行第j列这个人知道他的附件至少有a[i][j]个人,问这个表示附近有多少人的矩阵的可能情况是否存在,若存在则输出其中一种符合的情况。
题解:竟然是题目有说明有多种情况,我们就可以假设极端情况每个位置上都有人,只需要判断第1行、第r行和第1列、第c列,处于边界的特殊情况即可。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define endl  '\n'
using namespace std;
int a[3005][3005];
int main()
{
    ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);
   int t;cin>>t;
   while(t--)
   {
      int r,c,f=0;cin>>r>>c;
      for(int i=1;i<=r;i++)
      {
      	for(int j=1;j<=c;j++)
      	{
      		cin>>a[i][j];
      		if((i==1&&j==1)||(i==1&&j==c)||(i==r&&j==1)||(i==r&&j==c)){
      			if(a[i][j]>2)f=1;
			  }
			else if(i==1||i==r||j==1||j==c){
				if(a[i][j]>3)f=1;
			}
			else if(a[i][j]>4)f=1;  	
		}
	  }
	  if(f)cout<<"NO"<<endl;
	  else{
	  	cout<<"YES"<<endl;
	  	for(int i=1;i<=r;i++)
	  	{
	  		for(int j=1;j<=c;j++)
			{
				
				if((i==1&&j==1)||(i==1&&j==c)||(i==r&&j==1)||(i==r&&j==c))
				cout<<2<<" ";
				else if(i==1||i==r||j==1||j==c)
				cout<<3<<" ";
				else cout<<4<<" ";    	
			}
			cout<<endl;	
		}
	  }
   }
    return 0;
}

C - Element Extermination

题意:一个长度为n的数组,若a[i]<a[i+1],则可以消去a[i]或a[i+1]其中的一个,可以进行多次消去,问是否可以让数组最终消去成长度为1的数组。
题解:只要保证a[1]<a[n],不管2、3、4…n-2、n-1的大小都可以消成长度为1的数组 思维水题,比赛有时就需要大胆莽!

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define endl  '\n'
using namespace std;
int main()
{
    ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);
   	int t;cin>>t;
   	while(t--)
   	{
   		int n;cin>>n;
		vector<int>a(n,0);
		for(int i=0;i<n;i++)
		cin>>a[i];
		if(a[0]<a[n-1])cout<<"YES"<<endl;
		else cout<<"NO"<<endl;	
	}
    return 0;
}

D - Replace by MEX

题意:一个长度为n的数组,且保证了0≤a[i]≤n,进行EXM操作也就是可用1-n中的任意数交换数组a中的元素,要求在2n个EXM操作内使得数组变成单调不递减的数组,且可能有多种情况输出其中一种即可。
题解:首先明确可能有多种情况输出,所以只需要自己大胆尝试。
先判断是否已经满足题目a[i]<=a[i+1]的要求,若满足则无需进行操作
用桶记录0-n中出现的次数,找到最小且没出现过的数mex,
若mex=n,则说明说明其中0至n-1都出现了一次,只是顺序不对,且只有每个a[i]=i时才能保证a[i]<=a[i+1],故用i交换第一个a[i]!=i的a[i]
若mex<n时,则说明其中出现了重复的数,直接交换这个数即可。

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define endl  '\n'
using namespace std;
int main()
{
    ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);
   	int t;cin>>t;
   	while(t--)
	{
   		int n;cin>>n;
   		vector<int>a(n,0),ans;
		for(int i=0;i<n;i++)
		cin>>a[i];
   		while(1)
   		{
   			int f=1;vector<int>cnt(n+1,0);
   			for(int i=0;i<n-1;i++)
   			if(a[i]>a[i+1]){
   				f=0;break;
			}
			if(f)break;   
   			for(int i=0;i<n;i++)
   				cnt[a[i]]++;
   			int mex=0,p;
			for(;cnt[mex]>0;mex++);
			if(mex<n)p=mex;
			else{
				for(int i=0;i<n;i++)
				if(a[i]!=i){
					p=i;break;
				}
			}
			ans.push_back(p);
			a[p]=mex;
		}
		cout<<ans.size()<<endl;
		for(int i=0;i<ans.size();i++)
		cout<<ans[i]+1<<" ";
		cout<<endl;
	}
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值