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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章