zoukankan      html  css  js  c++  java
  • 2020上海高校程序设计竞赛暨第18届上海大学程序设计联赛夏季赛(同步赛)

    A.同源

    题目大意:gcd(a,b)=gcd(a,c)=gcd(b,c)=k,a+b+c=n,给出n,k,构造a,b,c(a,b,c!=k)。1<=n,k<=10^18

    题解:思维+构造 因为gcd(a,b)=gcd(b,c)=gcd(a,c)=k.说明a,b,c都为k的倍数,设a=x*k,b=y*k,c=z*k,a+b+c=x*k+y*k+z*k=(x+y+z)*k=n.所以x+y+z=n/k.并且gcd(x,y)=1,gcd(x,z)=1,gcd(y,z)=1,x,y,z!=1

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    using namespace std;
    
    int T;
    
    LL n,k;
    
    LL gcd(LL x,LL y)
    {
        return y==0?x:gcd(y,x%y);    
    }
     
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%lld%lld",&n,&k);
            if(n%k) 
            {
                cout<<"-1 -1 -1
    ";
                continue;
            }
            n=n/k;
            bool flag=false;
            for(LL i=2;i<=10;i++)
            {
                for(LL j=2;j<=10;j++)
                {
                    LL gg=n-i-j;
                    if(gg<2) break;
                    if(gcd(i,gg)==1&&gcd(i,j)==1&&gcd(j,gg)==1)
                    {
                        cout<<i*k<<" "<<j*k<<" "<<gg*k<<endl;
                        flag=true;
                        break;
                    }
                }
                if(flag) break;
            }
            if(!flag) cout<<"-1 -1 -1
    ";
        }
        return 0;
    }
    View Code

     


    B.分子

    题目大意:有机分子只能由 C, H, O 三种元素组成。根据珂学家们的探测,一个 C 原子的式量为 13 ,一个 H 原子的式量为 1 ,一个 O 原子的式量为 17 。一个有机分子的式量恰为各个原子的式量的总和。给出分子式,求分子式量。

    题解:字符串模拟+栈 具体解释见代码

    代码:

    #include<iostream>
    #include<cstdio>
    #include<stack>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    using namespace std; 
    
    int a[20];
    bool flag=false;
    stack<LL>st;
    
    int main()
    {
        string s;
        cin>>s;
        int len=s.length();
        LL ans=0; 
        a['C'-'A']=13;a['H'-'A']=1;a['O'-'A']=17;
        for(int i=0;i<len;i++)
        {
            if(s[i]=='(') flag=true,st.push(-1);//现在在括号里,入栈-1 
            if((s[i]=='H'||s[i]=='C'||s[i]=='O')&&flag&&(s[i+1]<'1'||s[i+1]>'9')) st.push(a[s[i]-'A']);//在括号里后一位不是数字直接入栈 
            if(flag==false&&(s[i]=='C'||s[i]=='H'||s[i]=='O')&&(s[i+1]<'1'||s[i+1]>'9')) ans+=a[s[i]-'A'];
            //没在括号里,并且后一位不是数字,直接计入答案
            //没在括号里,并且后一位是数字,统计 
            if(flag==false&&(s[i]=='C'||s[i]=='H'||s[i]=='O')&&(s[i+1]>='0'&&s[i+1]<='9'))
            {
                LL temp=a[s[i]-'A'],js=0;
                i++;
                while(s[i]>='0'&&s[i]<='9')
                {
                    js=js*10+s[i]-'0';
                    i++;
                }
                ans=ans+temp*js;
                i--;
            }  
            //在括号里,并且后一位是数字,累加 
            if(flag==true&&(s[i]=='C'||s[i]=='H'||s[i]=='O')&&(s[i+1]>='0'&&s[i+1]<='9'))
            {
                LL temp=a[s[i]-'A'],js=0;
                i++;
                while(s[i]>='0'&&s[i]<='9')
                {
                    js=js*10+s[i]-'0';
                    i++;
                }
                i--;
                st.push(js*temp); 
            }
            //右括号,出栈累加 
            if(s[i]==')')
            {
                flag=false; 
                LL temp=0;
                while(1)
                {
                    LL x=st.top();st.pop();
                    if(x==-1) break;
                    temp=temp+x; 
                }
                if((s[i+1]>='0'&&s[i+1]<='9')) 
                { 
                   i++;
                   LL js=0;
                   while(s[i]>='0'&&s[i]<='9')
                   {
                    js=js*10+s[i]-'0';
                    i++;
                   }
                // cout<<js<<"----"<<temp<<endl;
                   i--;
                   ans=ans+temp*js;
                 }else ans=ans+temp;
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    //CH3(CH2)10CH3
    //H(HH)C(CH2)3O(H)1 
    View Code

    C.爵士

    题目大意:查询字符串里有无字符‘2’

    题解:签到题

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            int n,nn=0;
            cin>>n;getchar();
            for(int i=1;i<=n;i++)
            {
                string s;
                getline(cin,s);
                int len=s.length();
               // cout<<s<<"----------"<<endl;
                for(int j=0;j<len;j++)
                {
                    if(s[j]=='2')
                    {
                        nn++;
                        break;
                    }
                }
            }
            printf("%.10lf
    ",1.*nn/n);
        }
        return 0;
    }
    View Code

    D.内存

    题目大意:一个模拟。。。

    题解:我先鸽了。。。

    代码:


    F.游戏

    题目大意:博弈。每轮选择树上一条边,收益为边两侧节点中较小的数量,不能取时,分数多的获胜。

    题解:发现先手必赢。解释


    G.选择

    题目大意:从n个数中选择n/2(向下取整),且第x个数必须选,并且不能选择相邻的数,求n/2个数的和的最大值。

    题解:DP  dp[i]表示1--i 选择i/2的数的最大值,因为第x个数必须选择,给a[x]+=INF,这样就保证在转移时第x个数一定会被取到。

    sum[i]为1--i,奇数位的数的前缀和。

    i为奇数时,dp[i]=max(dp[i-1],dp[i-2]+a[i]) (前者为不选,后者为选)

    i为偶数时,dp[i]=max(sum[i-1],dp[i-2]+a[i])(前者为不选,后者为选)

    ps:#define INF (1e16)就错...;n;(再也不用define了;n;)INF为1<<30也不对 举个极端数据就懂了

    代码 

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define N 200009
    #define LL long long
    using namespace std;
    const LL INF=1e16;
    
    int n,x;
    
    LL a[N],sum[N],dp[N];
    
    LL read()
    {
        LL x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    
    int main()
    {
        n=read();x=read();
        for(int i=1;i<=n;i++)
        {
            a[i]=read();
    //        cout<<a[i]<<"---"<<endl;
        }    
        a[x]+=INF; sum[1]+=a[1];
        for(int i=3;i<=n;i+=2)
        {
            sum[i]=sum[i-2]+a[i];
        }
        for(int i=2;i<=n;i++)
        {
            if(i&1)
            {
                dp[i]=max(dp[i-1],dp[i-2]+a[i]);
            }else
            {
                dp[i]=max(sum[i-1],dp[i-2]+a[i]);
            }
        }
        //cout<<INF<<endl;
        cout<<dp[n]-INF; 
        return 0;
    } 
    View Code
  • 相关阅读:
    Ansible 详细用法说明(一)
    Puppet基于Master/Agent模式实现LNMP平台部署
    推荐-zabbix原理篇
    Centos 6.x 安装Nagios及WEB管理nagiosql实现windows及linux监控指南
    CentOS 7下安装Logstash ELK Stack 日志管理系统(下)
    【Python基础学习二】定义变量、判断、循环、函数基本语法
    【Python基础学习一】在OSX系统下搭建Python语言集成开发环境 附激活码
    内联函数
    2016 科大讯飞校招研发一面二面 10.13
    hiho #1151 : 骨牌覆盖问题·二 (递推,数论)
  • 原文地址:https://www.cnblogs.com/zzyh/p/13462768.html
Copyright © 2011-2022 走看看