石油大--2020年秋季组队训练赛第十三场---- C、Colourful Chameleons(思维)

题面:
在这里插入图片描述

题意:
n n n 种颜色的变色龙,其中第 i i i 种颜色的变色龙有 a i , ( a i > = n − 1 ) a_i ,(a_i>=n-1) ai,(ai>=n1) 只。
我每次可以选择 n − 1 n-1 n1 只不同颜色的变色龙,让他们变成 y , y > = n − 1 y,y>=n-1 y,y>=n1 未选择的那种颜色的变色龙。

现在我想让所有的变色龙都变为第 c c c 种颜色,至少需要经过几次操作。

题解:
我们发现变化时,两个颜色之间的变色龙数量之间的差值只会变化 ( y + 1 ) (y+1) (y+1) 的倍数。
所以我们 c h e c k check check 他们之间的差值是否都是 ( y + 1 ) (y+1) (y+1)的倍数即能得到可行状态。因为保证了 a i > = n − 1 , y > = n − 1 a_i>=n-1,y>=n-1 ai>=n1,y>=n1 所以一定可以到达最终状态。

考虑操作最小值,那么一定是除去第 c c c 种颜色后,我们设剩余的变色龙的数量的最大值为 m a x x maxx maxx,如果操作要最小的话,那么这个 m a x x maxx maxx 每一次都减少即可,即需要操作 m a x x maxx maxx 次。

最终颜色为 c c c 的变色龙的数量为 ( m a x x − a n s ) ∗ y + a c − a n s (maxx-ans)*y+a_c-ans (maxxans)y+acans
其中 a n s ans ans 为,其余的变色龙数量达到 m a x x maxx maxx 需要的操作次数。因为 m a x x maxx maxx 每次都减少,所以最终只会操作 m a x x maxx maxx 次,其中有 a n s ans ans 次,颜色为 c c c 的变色龙不增加且减少 1 1 1

代码:

#pragma GCC optimize(2)
#pragma GCC optimize("Ofast","inline","-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<bitset>
#include<map>
#include<unordered_map>
#include<set>
namespace onlyzhao
{
    #define ui unsigned int
    #define ll long long
    #define llu unsigned ll
    #define ld long double
    #define pr make_pair
    #define pb push_back
    #define lc (cnt<<1)
    #define rc (cnt<<1|1)
    #define len(x)  (t[(x)].r-t[(x)].l+1)
    #define tmid ((l+r)>>1)
    #define fhead(x) for(int i=head[(x)];i;i=nt[i])
    #define max(x,y) ((x)>(y)?(x):(y))
    #define min(x,y) ((x)>(y)?(y):(x))
    #define one(n) for(int i=1;i<=(n);i++)
    #define rone(n) for(int i=(n);i>=1;i--)
    #define fone(i,x,n) for(int i=(x);i<=(n);i++)
    #define frone(i,n,x) for(int i=(n);i>=(x);i--)
    #define fonk(i,x,n,k) for(int i=(x);i<=(n);i+=(k))
    #define fronk(i,n,x,k) for(int i=(n);i>=(x);i-=(k))
    #define two(n,m) for(int i=1;i<=(n);i++) for(int j=1;j<=(m);j++)
    #define ftwo(i,n,j,m) for(int i=1;i<=(n);i++) for(int j=1;j<=(m);j++)
    #define fvc(vc) for(int i=0;i<vc.size();i++)
    #define frvc(vc) for(int i=vc.size()-1;i>=0;i--)
    #define forvc(i,vc) for(int i=0;i<vc.size();i++)
    #define forrvc(i,vc) for(int i=vc.size()-1;i>=0;i--)
    #define cls(a) memset(a,0,sizeof(a))
    #define cls1(a) memset(a,-1,sizeof(a))
    #define clsmax(a) memset(a,0x3f,sizeof(a))
    #define clsmin(a) memset(a,0x80,sizeof(a))
    #define cln(a,num) memset(a,0,sizeof(a[0])*num)
    #define cln1(a,num) memset(a,-1,sizeof(a[0])*num)
    #define clnmax(a,num) memset(a,0x3f,sizeof(a[0])*num)
    #define clnmin(a,num) memset(a,0x80,sizeof(a[0])*num)
    #define sc(x) scanf("%d",&x)
    #define sc2(x,y) scanf("%d%d",&x,&y)
    #define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define scl(x) scanf("%lld",&x)
    #define scl2(x,y) scanf("%lld%lld",&x,&y)
    #define scl3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)
    #define scf(x) scanf("%lf",&x)
    #define scf2(x,y) scanf("%lf%lf",&x,&y)
    #define scf3(x,y,z) scanf("%lf%lf%lf",&x,&y,&z)
    #define scs(x) scanf("%s",x+1)
    #define scs0(x) scanf("%s",x)
    #define scline(x) scanf("%[^\n]%*c",x+1)
    #define scline0(x) scanf("%[^\n]%*c",x)
    #define pcc(x) putchar(x)
    #define pc(x) printf("%d\n",x)
    #define pc2(x,y) printf("%d %d\n",x,y)
    #define pc3(x,y,z) printf("%d %d %d\n",x,y,z)
    #define pck(x) printf("%d ",x)
    #define pcl(x) printf("%lld\n",x)
    #define pcl2(x,y) printf("%lld %lld\n",x,y)
    #define pcl3(x,y,z) printf("%lld %lld %d\n",x,y,z)
    #define pclk(x) printf("%lld ",x)
    #define pcf2(x) printf("%.2f\n",x)
    #define pcf6(x) printf("%.6f\n",x)
    #define pcf8(x) printf("%.8f\n",x)
    #define pcs(x) printf("%s\n",x+1)
    #define pcs0(x) printf("%s\n",x)
    #define pcline(x) printf("%d**********\n",x)
    #define casett int tt;sc(tt);int pp=0;while(tt--)

    char buffer[100001],*S,*T;
    inline char Get_Char()
    {
        if (S==T)
        {
            T=(S=buffer)+fread(buffer,1,100001,stdin);
            if (S==T) return EOF;
        }
        return *S++;
    }
    inline int read()
    {
        char c;int re=0;
        for(c=Get_Char();c<'0'||c>'9';c=Get_Char());
        while(c>='0'&&c<='9') re=re*10+(c-'0'),c=Get_Char();
        return re;
    }
};
using namespace onlyzhao;
using namespace std;

const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const double dnf=1e9;
const int mod=998244353;
const double eps=1e-9;
const double pi=acos(-1.0);
const int hp=13331;
const int maxn=1000100;
const int maxm=100100;
const int up=100100;

ll a[maxn];

int main(void)
{
    ll n,c,y;
    ll val;
    scanf("%lld%lld%lld",&n,&c,&y);
    ll x,cnt=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&x);
        if(i==c) val=x;
        else a[++cnt]=x;
    }
    sort(a+1,a+cnt+1);
    ll maxx=a[cnt];
    bool flag=true;
    ll ans=0;
    for(int i=1;i<=cnt;i++)
    {
        if((a[cnt]-a[i])%(y+1)!=0)
        {
            flag=false;
            break;
        }
        ans+=(a[cnt]-a[i])/(y+1);
    }
    if(flag==false)
    {
        printf("impossible\n");
    }
    else
    {
        printf("%lld %lld\n",maxx,(maxx-ans)*y+val-ans);
    }
    return 0;

}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值