zoukankan      html  css  js  c++  java
  • 日常训练 2017.04.08 凶♂残♂的猪猪???

    前言:我从未见过如此凶残的猪。。。会修路,会撒猪粮,会高科技,会有闲情逸致玩数学,还会吃猪???看来我还是Naive

    ----------------------------------------------------------------------------------分割线-------------------------------------------------------------------------------------------------

    猪猪划船(boat)

    【题目描述】

    6只可爱的猪猪们一起旅游,其中有3只大猪A,B,C,他们的孩子为3只小猪a,b,c。由于猪猪们十分凶残,如果小猪在没有父母监护的情况下,和其他的大猪待在一起,就会被吃掉。

    拦在他们面前的是一条大河,河上有一只只有1个船桨且限载2只猪的小船,只有A,B,C,a会划船。他们独自划船单程需要的时间为tA,tB,tC,ta,如果搭载另一只猪时间翻倍。你需要求出所有小猪过河的最短时间。

    【输入数据】

    一行,4个整数,tA,tB,tC,ta。

    【输出数据】

    一行,一个整数,表示最短时间。

    【样例输入】

    10 10 10 10

    【样例输出】

    220

    【数据范围】

    对于20%的数据:tA=tB=tC=ta

    对于60%的数据:ta<=tA<=tB<=tC

    对于100%的数据:tA,tB,tC,ta<=100

    这是一道结论题,我们可以先手动尝试一下,发现合法的情况总数并不多(虽然我说的很轻松但是当时并没有尝试出全部的)

    我们就根据分类和不分类分成3个阶段取min就好啦

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int A,B,C,a,ans;
    inline void Jimmy(){
        scanf("%d%d%d%d",&A,&B,&C,&a);
        ans+=min(a*6,min((a+B)*3,(a+C)*3));    //阶段一 
        ans+=(B+C)*2+min(A,a)*2+min(B,C)*4+a;    //阶段二
        ans+=min(a*5,min(a*2+C*3,a*2+B*3));        //阶段三 
        printf("%d",ans);
    }
    int main(){
        freopen("boat.in","r",stdin);
        freopen("boat.out","w",stdout);
        Jimmy();
        return 0;
    }
    会吃猪的猪???

    小猪星球(planet)

    【题目描述】

    小猪所在的星系有n个星球,用1~n标号,其中有一些星球之间有单向的隧道相连。由于超时空隧道的存在,通过一个隧道的时间可能为0或负数。现在小猪们决定从1号星球出发,沿着最短路径到达n号星球。

    科学家猪小聪发明了一种神奇的装置,使得飞船在每个隧道中运行的时间都增加一个相同的常数(可以为0或负数),你需要确定这个常数使得旅途的总时间非负且最小。

    【输入数据】

    输入文件包含多组数据,第一行为数据组数T。

    对于每一组数据,第一行两个整数V,E,表示星球的个数和隧道的个数。接下来E行,每行3个整数i,j,t,表示从i号星球到j号星球有一条耗时为t的单向隧道。

    【输出数据】

    共T行,每行一个整数,表示从1号星球到n号星球最短的时间。如果不能从1号星球到达n号星球,输出-1。

    【样例输入】

    1

    4 5

    1 2 1

    1 3 1

    2 3 -3

    3 1 1

    3 4 1

    【样例输出】

    2

    【样例解释】

    如果不使用科技(也可以理解成是使用科技,但确定常数为0,所有的隧道时间不变),则1->2->3->1->2->3……->4的时间为负无穷,不符合要求。若使用科技,确定常数为1,则1->2->3->4的最短时间为2。

     

    【数据范围】

    对于100%的数据,N<=100,E<=N(N+1)/2,|t|<=10^5,i,j<=N

    友情提示:可能有重边和自环

    用floyd判自环,二分题目中的常数c,注意判负环

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    #define N 110
    #define M 5050
    #define inf 100000010
    using namespace std;
    int T,n,m,cnt,g[N],q[N*M],a[N][N],deg[N],dis[N],h,t,inq[N];
    struct Nee{
        int nxt,to,w;
    }e[M];
    inline int check2(int x){    //二分常数c 
        for(int i=1;i<=n;i++)    deg[i]=0,dis[i]=inf,inq[i]=0;
        int u=1,h=1,t=0;
        q[++t]=u;inq[u]=1;deg[u]++;dis[u]=0;
        while(h<=t){
            u=q[h++];inq[u]=0;
            for(int i=g[u];i;i=e[i].nxt){
                if(a[e[i].to][n]&&dis[u]+e[i].w+x<dis[e[i].to]){
                    dis[e[i].to]=dis[u]+e[i].w+x;
                    if(!inq[e[i].to]){
                        if(++deg[e[i].to]>m)    return -1;
                        q[++t]=e[i].to;
                        inq[e[i].to]=1;
                    }
                }
            }
        }
        return dis[n];
    }
    inline int check1(){        //检验是否能到达n 
        for(int i=1;i<=n;i++)    inq[i]=0;
        int u=1,h=1,t=0;q[++t]=u;inq[u]=1;
        while(h<=t){
            u=q[h++];
            for(int i=g[u];i;i=e[i].nxt){
                if(!inq[e[i].to]){
                    inq[e[i].to]=1;
                    q[++t]=e[i].to;
                }
            }
        }
        return inq[n];
    }
    inline void addedge(int x,int y,int z){
        e[++cnt].nxt=g[x];g[x]=cnt;e[cnt].to=y;e[cnt].w=z;
    }
    inline void Jimmy(){
        scanf("%d%d",&n,&m);
        cnt=0;
        for(int i=1;i<=n;i++)    g[i]=0;
        for(int i=1,j,k,w;i<=m;i++){
            scanf("%d%d%d",&j,&k,&w);
            addedge(j,k,w);
        }
        if(!check1()){
            printf("-1
    ");
            return;
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                a[i][j]=0;
        for(int i=1;i<=n;i++)
            for(int j=g[i];j;j=e[j].nxt)
                a[i][e[j].to]=1;
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    a[i][j]|=a[i][k]&a[k][j];
        a[n][n]=1;int l=-100001,r=100001;
        while(l<r){
            int mid=(l+r)>>1;
            if(check2(mid)>=0)        r=mid;
            else l=mid+1;
        }
        printf("%d
    ",check2(l));
    }
    int main(){
        freopen("planet.in","r",stdin);
        freopen("planet.out","w",stdout); 
        scanf("%d",&T);
        while(T--)
            Jimmy();
        return 0;
    } 
    猪猪星球

    小猪送货(deliver)

    【题目描述】

    小猪所在的星系有n个星球从左到右排成一排,用1~n标号。每个星球有建设有一个工厂,住着若干居民。猪粮是猪猪星系的重要的物资,第i个城市的工厂能够生产pi个单位的猪粮,第i个城市最多可以卖出si个单位猪粮。对于任意1<=i<j<=n,存在着一条从i到j的单向道路,最多可以通过这条道路运输c个单位的猪粮,你需要计算最多能够卖出多少猪粮。

    【输入数据】

    第一行两个整数n,c

    第二行n个整数,第i个整数表示pi

    第三行n个整数,第i个整数表示si

    【输出数据】

    一行,一个整数,表示最多可以卖出的猪粮的单位数

    【样例输入1】

    5 1

    7 4 2 1 0

    1 2 3 4 5

    【样例输出1】

    12

    【样例输入2】

    4 3

    13 10 7 4

    4 7 10 13

    【样例输出2】

    34

    【数据范围】

    对于20%的数据:c=0

    对于60%的数据:n<=100

    对于100%的数据:n<=10000,0<=c,pi,si<=10^9

    P.S.:差评!单身狗拒绝猪粮狗粮一切粮 QAQ !!!

    对于20分的数据我们在p和s里取个min求和就好啦

    对于60分的数据,考虑网络流,(P.S.艾特当时说我觉得这道题像网络流的老何)

    源点s向i建边,每个点向汇点t连边,两点之间从小到大ij也建边

    (s,i)=pi,(i,j)=c,(i,t)=si

    但是这样子边太多了不够优秀啊,怎么办呢?观察到这题的水流限度很特殊,只有pi,si和c,而且c的连边在数列上是有规律的,都为c的水流限度又可以看做和边的先后没有关系,那就是满足无后向性,我们考虑dp

    f[i]][j]表示以前i个点,有j个和t连边的最小割,那么就有f[i][j]=min{f[i-1][j]+j*c+p[i],f[i-1][j-1]+s[i]},对于源点出来的边对j没有影响,但是割掉之后因为是最小割(最小割即为最大流),那么割掉s的割边,由于还和t相连,所以j条与t相连的边可以流向它

    本题滋磁dp是由于水流限度的特殊性(均为s)以及1-n和建边i,j的从小到大保证了无后效性

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    #define N 10010
    #define min(a,b) (a<b?a:b)
    #define inf 10000000000010LL
    using namespace std;
    long long c,p[N],s[N],f[2][N],ans=inf;
    int n;
    inline void Jimmy(){
        scanf("%d%lld",&n,&c);
        for(int i=1;i<=n;i++)
            scanf("%lld",&p[i]);
        for(int i=1;i<=n;i++)
            scanf("%lld",&s[i]);
        for(int i=1;i<=n;i++)
            f[0][i]=f[1][i]=inf;
        f[1][0]=p[1];f[1][1]=s[1];
        for(int i=2;i<=n;i++){
            f[i&1][0]=f[i&1^1][0]+p[i];
            for(int j=1;j<=n;j++)
                f[i&1][j]=min(f[i&1^1][j]+1LL*j*c+p[i],f[i&1^1][j-1]+s[i]);
        }
        for(int i=0;i<=n;i++)
            ans=min(ans,f[n&1][i]);
        printf("%lld",ans);
    }
    int main(){
        freopen("deliver.in","r",stdin);
        freopen("deliver.out","w",stdout);
        Jimmy();
        return 0;
    }
    拒绝猪粮 QAQ!!!

    小猪数数(math)

    【题目描述】

    猪小聪和猪小明在一个小时的时间里,A完了前三题,他们无聊地说:“咱们来玩个游戏消磨时间吧……”

    在这个游戏中,猪小聪和猪小明每个人手上有一台电脑,一开始双方的电脑上的数字都是1。现在猪小聪和猪小明按照任意的顺序执行操作a=a+b(其中a为自己电脑上的数字,b为对方电脑上的数字),例如按照小聪-小明-小明执行后双方的数字为2 5。

    现在在他们玩了若干轮之后,双方电脑上的数字为N M,可惜的是他们忘记了他们到底玩了多少轮,你需要求出他们至少玩了多少轮。

    【输入数据】

    2个整数,表示N,M。

    【输出数据】

    1个整数,表示最少玩过的轮数。如果根本不可能出现符合要求的结果,输出-1。

    【样例输入1】

    2 5

    【样例输出1】

    3

    【样例输入2】

    2 2

    【样例输出2】

    -1

    【数据范围】

    对于30%的数据,1<=N,M<=10

    对于60%的数据,1<=N,M<=1000

    对于100%的数据:N,M和ans均不会爆long long (ans表示输出的答案)

    本套题的水题呀,YY一下过程很容易发现这就是更相减损的过程,我们用%来代替就好了,也就是求gcd的过程中累计答案

    当然对于gcd(n,m)不为1的输出-1就好了

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    long long n,m,ans;
    inline long long gcd_(long long x,long long y){
        return y==0?x:gcd_(y,x%y);
    }
    inline void gcd(long long x,long long y){
        if(y==0) return;
        ans+=x/y;
        gcd(y,x%y);
    }
    inline void Jimmy(){
        scanf("%lld%lld",&n,&m);
        if(gcd_(n,m)!=1){
            printf("-1");
            return;
        }
        gcd(n,m);
        printf("%d",ans-1);
    }
    int main(){
        freopen("math.in","r",stdin);
        freopen("math.out","w",stdout);
        Jimmy();
        return 0;
    }
    猪猪数学
  • 相关阅读:
    Python笔记-面向对象编程
    大学课后答案微信小程序项目实践(1)
    用weexplus从0到1写一个app(2)-页面跳转和文章列表及文章详情的编写
    react基础学习和react服务端渲染框架next.js踩坑
    基于weex的app开发脚手架weexplus学习笔记
    用weexplus从0到1写一个app
    Vue与React两个框架的区别对比
    mpvue学习笔记-之微信小程序数据请求封装
    Flutter/Dart import导入文件关键字总结
    55个提高你CSS开发效率的必备片段(转自:前段日刊)
  • 原文地址:https://www.cnblogs.com/JimmyC/p/6686483.html
Copyright © 2011-2022 走看看