A - Sign Flipping
题意:问你至少有(n-1)/ 2个a[i+1]-a[i]大于等于0,至少有(n-1)/ 2个a[i+1]-a[i]小于等于0,你可以变化每个数的正负。
题解:这样的话就可以正负交替输出了。
/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 110;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;
int a[maxn];
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i=0;i<n;i++) scanf("%d",&a[i]);
for(int i=0;i<n;i++){
if(i%2==0){
printf("%d ",abs(a[i]));
}
else printf("%d ",-abs(a[i]));
}
cout<<endl;
}
return 0;
}
B - Neighbor Grid
题解:看一张图你就懂了,只需要判断一下输入进去的数有没有超过每个格子的最大值,然后输出即可(临两条边输出2,临一条边输出3,不临边输出4)
/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 1e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;
vector<int> v[maxn];
int main()
{
int t;
cin>>t;
while(t--){
for(int i=0;i<maxn;i++) v[i].clear();
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
int x;
scanf("%d",&x);
v[i].push_back(x);
}
}
bool flag=true;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if((i==0&&j==0)||(i==0&&j==m-1)||(i==n-1&&j==0)||(i==n-1&&j==m-1)){
if(v[i][j]>2) flag=false;
}
else if(i==0||i==n-1){
if(v[i][j]>3) flag=false;
}
else if(j==0||j==m-1){
if(v[i][j]>3) flag=false;
}
else {
if(v[i][j]>4) flag=false;
}
}
}
if(flag==false)
cout<<"NO"<<endl;
else{
cout<<"YES"<<endl;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if((i==0&&j==0)||(i==0&&j==m-1)||(i==n-1&&j==0)||(i==n-1&&j==m-1)){
printf("2 ");
}
else if(i==0||i==n-1){
printf("3 ");
}
else if(j==0||j==m-1){
printf("3 ");
}
else {
printf("4 ");
}
}
printf("\n");
}
}
}
return 0;
}
C - Element Extermination
题解:判断第一个数是否小于最后一个数
证明如下(并不规范):每次在除首末两段的中间,找出最大最小值,把最大值前边的和最小值后边的都删了,重叠就对边取一个,然后用边界的值删掉它,重复这个过程即可。
/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 3e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;
int a[maxn];
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i=0;i<n;i++) scanf("%d",&a[i]);
if(a[0]<a[n-1]) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
D - Replace by MEX
题解:构造一个0 1 2 3…n-1的数列即可。
特殊情况:如果mex=n的话,我们随便找一个a[i]!=i的地方将mex先暂时放入,每次暴力查找mex,判断是否符合条件即可。
注意:输出的结果是数组下标+1(这里数组下标指的是从0开始)
/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
const int maxn = 1010;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 100000000;
using namespace std;
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
int n;
int a[maxn];
vector <int> ans;
bool visited[maxn];
int ifind(){
memset(visited,false,sizeof(visited));
for(int i=0;i<n;i++) visited[a[i]]=true;
for(int i=0;i<=n;i++){
if(!visited[i]) return i;
}
}
bool check(){
for(int i=0;i<n;i++){
if(a[i]!=i) return false;
}
return true;
}
int main()
{
int t;
cin>>t;
while(t--){
cin>>n;
ans.clear();
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
while(!check()){
int mex=ifind();
if(mex==n){
for(int i=0;i<n;i++){
if(a[i]!=i){
a[i]=mex;
ans.push_back(i+1);
break;
}
}
}
else{
ans.push_back(mex+1);
a[mex]=mex;
}
}
printf("%d\n",ans.size());
for(int i=0;i<ans.size();i++){
printf("%d ",ans[i]);
}
cout<<endl;
}
return 0;
}