比賽連接: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;
}