题型——构造题

﹥>﹥吖頭↗ 提交于 2020-04-06 22:42:06

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;
}
483C

 

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;
}
931C

 

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;
}
268C

 

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;
}
View Code

 

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;
}
View Code

 

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;
}
View Code

 

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;
}
View Code

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!