• CF26E


    一道很有趣的题...难度并不是很大,基本可以接受

    显然这是一个构造问题

    我们分成几类进行讨论:

    首先,如果目标是非正数,那一定是不可能的(显而易见)

    然后,如果目标比允许操作的和还要大,那也是不可能的

    剩下的情况就不那么显然了,我们先假设有解再进行讨论

    (插播一句:强烈建议食用样例!!!对正解有很大启发!!!)

    首先,如果需要构造的值比所有操作数中的最小值还要小(如样例2),怎么办?

    样例2给出了较为明确的思想:

    我们记录两个位置,一个是最小操作数的位置,另一个随意

    我们的目标是用最小操作数的位置来构造出答案

    我们在第二个位置上先记录一下一开始的值,然后把剩余所有位置上多余的部分全跑完,但是把最小操作数的位置上保留足够构造出答案的操作数

    然后在第二个位置上再点一次,这样就把$y$更新回了1

    然后在最小值的位置上记录下当前$y$的值,再把第二个位置多余的操作跑完

    再在最小值位置点完,就能成功构造出目标了

    可是这里有一个问题:如果目标是1呢?这样做出来能构造出的目标至少是2啊!

    所以如果目标是$1$,却没有任何一个操作数是1,那么就是无解的!

    如果有呢?

    那种可以和下一种情况合并

    下一种情况自然就是需要构造的值比最小值要大

    这样的话,最小值即使跑满也不会超标

    因此我们在最小值的位置上先记录下$y$,然后把别的多余的部分跑满,最后利用原来记录的位置把$y$改回去,然后跑满即构造出了答案

    这样就结束了

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    int num[105];
    int n,w;
    int sum=0,minv=0x3f3f3f3f;
    int main()
    {
        freopen("brand.in","r",stdin);
        freopen("brand.out","w",stdout);
        scanf("%d%d",&n,&w);
        int posi=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&num[i]);
            sum+=num[i];
            if(minv>num[i])minv=num[i],posi=i;
        }
        if(w<=0||sum<w){printf("Toushui
    ");return 0;}
        if(w<minv)
        {
            if(w==1){printf("Toushui
    ");return 0;}
            int pp=0;
            for(int i=1;i<=n;i++)if(i!=posi&&num[i]){pp=i;num[i]--;break;}
            if(!pp){printf("Toushui
    ");return 0;}
            printf("Yuyue
    ");
            printf("%d ",pp);
            while(num[posi]+1>w)printf("%d %d ",posi,posi),num[posi]--;
            for(int i=1;i<=n;i++)
            {
                if(i==pp||i==posi)continue;
                while(num[i])printf("%d %d ",i,i),num[i]--;
            }
            printf("%d %d ",pp,posi);
            while(num[pp])printf("%d %d ",pp,pp),num[pp]--;
            printf("%d ",posi),num[posi]--;
            while(num[posi])printf("%d %d ",posi,posi),num[posi]--;
            printf("
    ");
        }else 
        {
            printf("Yuyue
    ");
            printf("%d ",posi);
            int res=sum-w;
            for(int i=1;i<=n;i++)
            {
                if(i==posi)continue;
                while(num[i])
                {
                    if(res)printf("%d %d ",i,i),res--,num[i]--;
                    if(!res)break;
                }
                if(!res)break;
            }
            printf("%d ",posi);
            num[posi]--;
            for(int i=1;i<=n;i++)while(num[i])printf("%d %d ",i,i),num[i]--;
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    谈谈toLocaleString()
    如何理解NaN?
    Element--->>>最新骨架屏Skeleton使用
    自定义select组件
    微信小程序之配置业务域名踩过的坑
    Vue watch监听 date中的变量 与 数组或者对象的数据变化
    Vue + Element table的@select方法获取当table中的id值都相同时,获取他们索引
    Vue + Element table中的某行触发enter事件后,使该行disabled
    Vue + Element tree树形控件的懒加载使用
    Vue web使用LeapFTP 上传到服务器
  • 原文地址:https://www.cnblogs.com/zhangleo/p/10885633.html
Copyright © 2020-2023  润新知