• 2016年中国大学生程序设计竞赛(杭州)-重现赛【01,02,03,06】


    说些感触。

    = =、哎,说起来重现还真是好气啊。

    出去的大二过去两题打铁,今天我们队边玩边打过了4题,有点不甘心啊。= =、对教练略无奈。

    -------------------------

    比赛经验:

    今天一开始,我洗完澡回来,比赛已经开始15分钟了,yhp和zmy都还在看题意,然后zmy在我来的时候已经在敲02了(其实是03,他说是02),然后我就和yhp讨论01,01yhp说完题意,一脸蒙比,因为知道01是水题吧,所以就开始瞎yy........(中间yy略去),后来我们过了01(wa了很多,我记得第一发T了,数组开小,这种低智商的错误也犯了)。然后窝去找zmy看03,C题一读完,卧槽,那么简单。。。zmy陷入了一个很烂的思路(其实这个每个人都有),但是严重的是,如果是现场赛,那不就完蛋了。我一直在想一个最不好的情况,那就是两个人在搞一道题目,而另一个人陷入了一道不是很难的水题不能自拔。这是最烂的,首先zmy因为这题(后来yhp和窝开始重新搞,wa了一发,也过了)心态不好了,心态很重要很重要!!比赛的时候心态很重要,不要脸地说,今天4题有3题基本上是我主导思路,然后过的,自信很重要,心态很重要!后来搞那个06,yhp瞎yy了一个方案,后来zmy搞出来在<8的情况是错的,后来一致决定<8暴力,然后wa了,因为输出用了%d....2333,最后的02,一直想一直想,最后队友给我讲了有可能环带有支路,那么就是强连通缩点,搞完1A。

    应该在现场赛就能拿铜了。。。。。心好痛。。。。。。

    不过真的,今天边玩边打场,比赛经验就是:心态很重要!

    还有以后的策略,除非是很水很水的题,操盘>=两个人!而另一个人要死命去读别的题,做好一旦那个题A出或者没A出的衔接工作,每个人都要有担当;

    写几发题解;

    ---------------

    11还在酝酿。。。。。。


    01:

    题意:

    给你n个值,让你搞成m个相等的值,一种操作是把a[i]只能分成相邻两部分,另一种操作是把a[i]和a[i+1]合并,求最小操作数;

    思路:

    首先肯定是求个所有值的sum,并且sum%m==0,搞一个平均值aver

    就是如果对于当前a[i]<aver,那么就往前面拿,如果是a[i]+a[i+1]<=aver那么就是直接合并,最后出来的时候判断一下a[i]就好了;

    如果对于a[i]>aver,那么就要分,那么肯定是分aver出去,分到小于等于aver为止,然后还要处理剩下的;

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    #include <queue>
    #include <stack>
    using namespace std;
    #define INF 0x3f3f3f
    #define pi acos(-1.0)
    #define mod 9973
    typedef long long LL;
    
    const int MAX=100010;
    LL n,m;
    LL a[MAX];
    
    int main()
    {
        LL t,i,j;
        scanf("%d",&t);
        int cas=1;
        while(t--)
        {
            LL sum=0;
            scanf("%d%d",&n,&m);
            for(i=0;i<n;i++)
            {
                scanf("%lld",&a[i]);
                sum+=a[i];
            }
            printf("Case #%d: ",cas++);
            if(sum%m!=0)
            {
                printf("-1
    ");
                continue;
            }
            LL aver=sum/m;
            LL cont=0;
            for(i=0;i<n;i++)
            {
                if(a[i]<aver)
                {
                    LL tmp=a[i];
                    while(i+1<n&&(tmp+a[i+1])<=aver)
                    {
                        tmp+=a[i+1];
                        i++;
                        cont++;
                    }
                    if(tmp<aver)
                    {
                        cont+=2;
                        a[i+1]-=aver-tmp;
                    }
                }
                else if(a[i]>aver)
                {
                    while(a[i]>aver)
                    {
                        cont++;
                        a[i]-=aver;
                    }
                    if(i+1<n&&a[i]<aver)
                    {
                        LL tmp=a[i];
                        while(i+1<n&&(tmp+a[i+1])<=aver)
                        {
                            tmp+=a[i+1];
                            i++;
                            cont++;
                        }
                        if(tmp<aver)
                        {
                            cont+=2;
                            a[i+1]-=aver-tmp;
                        }
                    }
                }
            }
            printf("%lld
    ",cont);
        }
        return 0;
    }

    02:

    题意:

    给你n个炸弹(一开始理解成了灯。。)的坐标,范围,花费,a炸了,b在a炸弹的边界或者里面,b也炸了,以此类推;

    思路:

    强连通,缩点,然后取一个点集里面最小的花费作为这个点的花费,然后把入度为零的点的花费加起来就好了;

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <queue>
    #include <stack>
    using namespace std;
    const double INF = 0x3f3f3f3f;
    typedef long long LL;
    const int N = 1e3+10;
    
    
    struct asd{
        LL x;
        LL y;
        LL w;
        LL cash;
    };
    asd q[N];
    int pre[N];
    int ma[N][N];
    int dfn[N];
    int low[N];
    int stap[N];
    int vis[N];
    int in[N];
    int tp,p,cnt;
    LL ww[N];
    int kr[N];
    int n;
    
    bool Judge(int i,int j)
    {
        if(i==j)
            return false;
        if(((q[i].x-q[j].x)*(q[i].x-q[j].x)+(q[i].y-q[j].y)*(q[i].y-q[j].y))<=(q[i].w*q[i].w))
            return true;
        return false;
    }
    
    void tarjan(int u)
    {
        dfn[u]=low[u]=++tp;
        stap[++p]=u;
        vis[u]=1;
        for(int i=1;i<=n;i++)
        {
            if(!ma[u][i])
                continue;
            if(!dfn[i])
            {
                tarjan(i);
                low[u]=min(low[u],low[i]);
            }
            else if(vis[i])
            {
                low[u]=min(low[u],dfn[i]);
            }
        }
        if(dfn[u]==low[u])
        {
            cnt++;
            int temp;
            while(1)
            {
                temp=stap[p];
                vis[temp]=0;
                in[temp]=cnt;
                ww[cnt]=min(ww[cnt],q[temp].cash);
                p--;
                if(temp==u)
                {
                    break;
                }
            }
        }
    }
    void fun()
    {
    
        memset(kr,0,sizeof(kr));
    
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(ma[i][j]&&in[i]!=in[j])
                {
                    kr[in[j]]++;
                }
            }
        }
        LL ans=0;
        for(int i=1;i<=cnt;i++)
        {
            if(!kr[i])
            {
                ans+=ww[i];
            }
        }
        printf("%lld
    ",ans);
    }
    
    void init()
    {
        memset(ma,0,sizeof(ma));
        memset(vis,0,sizeof(vis));
        memset(dfn,0,sizeof(dfn));
        memset(ww,INF,sizeof(ww));
    }
    
    int main()
    {
        int T,cas=1;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
                scanf("%lld%lld%lld%lld",&q[i].x,&q[i].y,&q[i].w,&q[i].cash);
            init();
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(Judge(i,j))
                        ma[i][j]=1;
                }
            }
    
            tp=p=cnt=0;
            for(int i=1;i<=n;i++)
            {
                if(!dfn[i])
                {
                    tarjan(i);
                }
            }
            printf("Case #%d: ",cas++);
            fun();
        }
        return 0;
    }

    03:

    题意:

    有一辆车,通过n个位置,通过每个位置的时间点都是整数,在整个过程中车的速度是非递减的。

    思路:

    那么就是说最后那个区间速度最大,时间最短,而且是整数秒,那么就是1秒,然后对于每个区间就是求一个向上取整时间(以前和队友考虑过)(n+m-eps)/m;

    (被除数+除数-精度)/除数;)也没怎么注意就用了long long

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    #include <queue>
    #include <stack>
    using namespace std;
    #define INF 0x3f3f3f
    #define pi acos(-1.0)
    #define mod 9973
    typedef long long LL;
    
    const double eps=1e-6;
    const int MAX=100010;
    int n,m;
    double a[MAX],b[MAX];
    
    int main()
    {
        int i,j;
        int t;
        scanf("%d",&t);
        int cas=1;
        while(t--)
        {
            scanf("%d",&n);
            for(i=1;i<=n;i++)
            {
                if(i==1)
                {
                    scanf("%lf",&a[i]);
                    b[i]=a[i];
                }
                else
                {
                    scanf("%lf",&a[i]);
                    b[i]=a[i]-a[i-1];
                }
            }
            double tmp=b[n];
            LL ans=0;
            ans+=1;
            for(i=n-1;i>=1;i--)
            {
                if(b[i]<=tmp)
                {
                    ans+=1;
                    tmp=b[i];
                }
                else
                {
                    LL tt=(b[i]+tmp-eps)/tmp;
                    ans+=tt;
                    tmp=b[i]/(double)tt;
    //                printf("%lld
    ",tt);
                }
    //            printf("%lf
    ",tmp);
            }
            printf("Case #%d: ",cas++);
            printf("%lld
    ",ans);
        }
        return 0;
    }

    06:

    题意:

    给你一串数,让你依次分割成5串,做+-*/运算,*/优先,求最大值;

    思路:

    队友一开始想就是前面位数越多越好,就是两种可能首位+第二位到倒数第四位或者首位到倒数第五位构成的数+倒数第四位;

    后来长度为6或7的时候有出路,一致同意<=8的情况下暴力,然后用暴力测所有情况,感觉没问题就过了;

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    #include <queue>
    #include <stack>
    using namespace std;
    #define INF 0x3f3f3f
    #define pi acos(-1.0)
    #define mod 9973
    typedef long long LL;
    
    const double eps=1e-6;
    const int MAX=100010;
    int n,m;
    
    char s[21];
    
    LL get_num(int ss,int t)
    {
        LL ans=0;
        for(int i=ss; i<t; i++)
        {
            ans=ans*10+s[i]-'0';
        }
        return ans;
    }
    
    int main()
    {
        int i,j,k,h;
        int t;
        scanf("%d",&t);
        int cas=1;
        while(t--)
        {
            scanf("%s",s);
            printf("Case #%d: ",cas++);
            n=strlen(s);
            LL ans1=0;
            ans1=(s[n-3]-'0')*(s[n-2]-'0')/(s[n-1]-'0');
            ans1=-ans1;
            LL sum1=0,sum2=0;
            if(n<=8)
            {
                LL ans=-INF;
                for(i=1; i<(n-3); i++)
                {
                    for(j=i+1; j<(n-2); j++)
                    {
                        for(k=j+1; k<(n-1); k++)
                        {
                            for(h=k+1; h<n; h++)
                            {
    //                            printf("%d %d %d %d 
    ",i,j,k,h);
                                ans=max(ans,get_num(0,i)+get_num(i,j)-get_num(j,k)*get_num(k,h)/get_num(h,n));
    //                            printf("%lld
    ",ans);
                            }
                        }
                    }
                }
                printf("%lld
    ",ans);
                continue;
            }
            for(i=0; i<n-4; i++)
            {
                sum1=sum1*10+s[i]-'0';
            }
            for(i=1; i<=n-4; i++)
            {
                sum2=sum2*10+s[i]-'0';
            }
            sum1+=s[n-4]-'0';
            sum2+=s[0]-'0';
            LL sum=max(sum1,sum2);
            printf("%lld
    ",sum+ans1);
    
    
        }
        return 0;
    }



  • 相关阅读:
    PHP 数组函数分类整理
    mysql 数据库中 int(3) 和 int(11) 有区别么???
    理解PHP的运行机制
    类与对象
    PHP函数补完:call_user_func()
    linux 软件安装目录详解
    Linux下安装Redis
    Redis简介,应用场景,优势
    idea自动抽取变量快捷键设置
    全局捕获异常(适用于SpringMvc,SpringBoot项目)
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6216769.html
Copyright © 2020-2023  润新知