cf 483C
第一个数设为a[1]=1,后一个数a[2]=a[1]+k,a[3]=a[2]-(k-1),a[4]=a[3]+(k-2),依次构造下去,剩下的数让他们按从小到大依个排下去,不会增加distinct elements的个数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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
很明显如果要进行操作,要么是把中间那个数拆最大值最小值,或是最大值最小值合并成中间那个数,那就是比较两者谁最优的问题了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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)不能放,那么只需取最小边的反对角线的点就行了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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组这种数据即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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
相邻两数相减使得差分数组无重复,那么只需最小最大值相互输出,逐步逼近。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }