cf 483C
第一个数设为a[1]=1,后一个数a[2]=a[1]+k,a[3]=a[2]-(k-1),a[4]=a[3]+(k-2),依次构造下去,剩下的数让他们按从小到大依个排下去,不会增加distinct elements的个数

#include <bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef long long ll;
const int maxn = (1<<21)+100;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
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;}
ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
int n,m,f,k,i;
int main()
{
n=read(),m=read();
f=k=1;
for (i=m;i>=1;i--)
{
cout<<k<<" ";
k+=i*f;
f*=-1;
}
cout<<k<<" ";
for (i=m+2;i<=n;i++) cout<<i<<" ";
return 0;
}
cf 931C
很明显如果要进行操作,要么是把中间那个数拆最大值最小值,或是最大值最小值合并成中间那个数,那就是比较两者谁最优的问题了。

#include <bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
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;}
ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
int n,maxx,minn,i,a[maxn];
map<int ,int> mapp;
int main()
{
n=read();
maxx=-INF,minn=INF;
for (i=1;i<=n;i++)
{
a[i]=read();
maxx=max(maxx,a[i]);
minn=min(minn,a[i]);
mapp[a[i]]++;
}
if (maxx-minn==2)
{
if (mapp[minn+1]==mapp[minn] && mapp[minn+1]==mapp[maxx])
{
cout<<mapp[minn+1]<<endl;
for (i=1;i<=n;i++) cout<<minn+1<<" ";
return 0;
}
int k1=mapp[minn+1]+abs(mapp[minn]-mapp[maxx]);
int k2=mapp[minn]+mapp[maxx]+(mapp[minn+1]%2);
if (k1>=k2)
{
cout<<k2<<endl;
for (i=1;i<=mapp[minn];i++) cout<<minn<<" ";
for (i=1;i<=mapp[maxx];i++) cout<<maxx<<" ";
for (i=1;i<=mapp[minn+1]/2;i++) cout<<maxx<<" "<<minn<<" ";
if (mapp[minn+1]%2) cout<<minn+1<<" ";
return 0;
}
else if (mapp[maxx]>mapp[minn])
{
cout<<k1<<endl;
for (i=1;i<=mapp[minn];i++) cout<<maxx-1<<" "<<minn+1<<" ";
for (i=1;i<=mapp[maxx]-mapp[minn];i++) cout<<maxx<<" ";
for (i=1;i<=mapp[minn+1];i++) cout<<minn+1<<" ";
return 0;
}
else
{
cout<<k1<<endl;
for (i=1;i<=mapp[maxx];i++) cout<<maxx-1<<" "<<minn+1<<" ";
for (i=1;i<=mapp[minn]-mapp[maxx];i++) cout<<minn<<" ";
for (i=1;i<=mapp[minn+1];i++) cout<<minn+1<<" ";
return 0;
}
}
else
{
cout<<n<<endl;
for (i=1;i<=n;i++) cout<<a[i]<<" ";
}
return 0;
}
cf 268C
首先一条竖线、横线只可能放一个点,同时(0,0)不能放,那么只需取最小边的反对角线的点就行了。

#include <bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
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;}
ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
int n,m,k,i;
int main()
{
n=read(),m=read();
k=min(m,n);
cout<<k+1<<endl;
for(i=0;i<=k;i++)
cout<<i<<" "<<k-i<<endl;
return 0;
}
cf 743C
把2/n分成两份,一份就给x=n,另一份就给y=n+1,z=n*(n+1)

#include <bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
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;}
ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
int n;
int main()
{
n=read();
if (n==1) cout<<-1<<endl;
else
cout<<n<<" "<<n+1<<" "<<n*(n+1)<<endl;
return 0;
}
cf 359B
要求一大段东西,首先看到2k<=n,而且给出k之后要乘以2,则说明得出的差值必定为偶数,尝试构造一组数据x x+1,相邻两项前一个和式无影响,后一样相差2,所以只需输出k/2组这种数据即可。

#include <bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef long long ll;
const int maxn = (1<<21)+100;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
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;}
ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
int n,m,i;
int main()
{
n=read(),m=read();
n*=2;
for (i=1;i<=m;i++)
{
cout<<n-1<<" ";
cout<<n<<" ";
n-=2;
}
for (i=n;i;i-=2) cout<<i<<" "<<i-1<<" ";
return 0;
}
cf 361B
数组值等于它的下标值时则算满足了一次,则只需输出m次数组值等于它的下标值的情况,为处理剩下的数,这里从大到小输出。
而剩下的数,只需与其相邻的数交换个位置即可。注意的是m=n时是无解的。因为gcd(1,1)=1

#include <bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
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;}
ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
int n,m,i,b[maxn];
int main()
{
n=read(),m=read();
if (m==n) cout<<-1<<endl;
else
{
for (i=n-m;i>0;i-=2)
{
if (i-1>0) b[i]=i-1,b[i-1]=i;
}
for (i=1;i<=n;i++)
if (b[i]==0) cout<<i<<" ";
else cout<<b[i]<<" ";
}
return 0;
}
cf 53C
相邻两数相减使得差分数组无重复,那么只需最小最大值相互输出,逐步逼近。

#include <bits/stdc++.h>
#define mp make_pair
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
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;}
ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;}
int n,l,r,f;
int main()
{
n=read();
l=1,r=n;
f=1;
while (l<=r)
{
if (f==1)
{
cout<<l<<" ";
l++;
f=f*(-1);
}
else
{
cout<<r<<" ";
r--;
f=f*(-1);
}
}
return 0;
}
来源:https://www.cnblogs.com/Y-Knightqin/p/12649914.html
