zoukankan      html  css  js  c++  java
  • 2019年湘潭大学程序设计竞赛(重现赛)

    https://ac.nowcoder.com/acm/contest/893#question

    湘潭大学的校赛 断断续续的作终于ak了 看了不少题解(菜就直说)

    A   Who's better?

    签到题

    #include<bits/stdc++.h>
     
    using namespace std;
     
    int main()
    {
        int n1,n2,t1,t2,s1,s2;
        cin>>n1>>t1>>s1;
        cin>>n2>>t2>>s2;
        if(n1>n2)
        {
            cout<<1;
            return 0;
        }
        if(n1<n2)
        {
            cout<<2;
            return 0;
        }
        if(t1<t2)
        {
            cout<<1;
            return 0;
        }
        if(t1>t2)
        {
            cout<<2;
            return 0;
        }
        if(s1<s2)
        {
            cout<<1;
            return 0;
        }
        if(s1>s2)
        {
            cout<<2;
            return 0;
        }
        cout<<"God";
     }

     B   Number

    也是水题,直接模拟:

    #include <bits/stdc++.h>
    using namespace std;
     
    int main(){
        int t;
        cin>>t;
        while(t--){
            int n;
            cin>>n;
            int ans=0;
            while(n>1){
                ans++;
                if(n%10==0) n/=10;
                else n+=1;
            }
            cout<<ans<<endl;
        }
        return 0;
    }

    C   Math Problem

    打表发现a为等差数列,公差为192(其实可以推出来的,但是我懒

    #include<bits/stdc++.h>
     
    using namespace std;
     
    int main()
     
    {
        long long int t,l,r,sum;
        cin>>t;
        while(t--)
        {
            cin>>l>>r;
            if((l-1)%192!=0)
            l=l+192-(l-1)%192;
            r=r-(r-1)%192;
            sum=(l+r)*((r-l)/(192)+1)/2;
            cout<<sum<<endl;
        }
    }

     D   Stone

    这个题我一开始想到的是之前在洛谷做的一道题 仔细看一下又有不同 把握两个条件:第一是任意的两堆石子都可以合并 第二 是合并的时候耗费的体力由小的那一堆石子决定

    我们假设有3堆石子 重量分别为 1 3 5

    那么如果1和3先合并 耗费1点体力 然后在和5合并 那么耗费4点体力 总共耗费5点体力

    但是如果3和5先合并 那么耗费3点体力 再和1合并 那么就耗费1点体力 一共耗费4点体力

    两种选择的根本在于 第一种选择把第一堆石子的重量多累积了一次 这就是从小到大合并的弊端

    所以我们要从大到小合并 这样所耗费的体力 就是石子重量的总和-最重的石子

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e4+5;
    typedef long long ll;
    int a[N];
    int main(){
        int t;
        cin>>t;
        while(t--){
            int n;
            cin>>n;
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
            sort(a+1,a+1+n);
            ll ans=0;
            for(int i=1;i<=n-1;i++){
                ans+=a[i];
            }
            cout<<ans<<endl;
        }
        return 0;
    }

    E   Watermelon

    要保证lililalala打扫卫生 就必须让别人吃西瓜的时候有西瓜能吃 在lililalala吃的时候没有西瓜可吃(这不是废话嘛........)

    但是每个人吃的西瓜数是一个区间的(1,a[i]),所以我们维护一个区间(l,r) 代表当前能吃的西瓜数 对于每一个非lililalala的人 因为最少可以只吃1个 那么就让r--,因为最多可以吃a[i]个 就让l-=a[i]

    而对于lililalala 因为他只会吃a[i]个 所以l和r都要-a[i]

    当对于一个非lililalala人来说 如果r<=0,代表前面的人再怎么节约着吃也没得吃了.....就是NO

    当对于lililalala来说 如果l<=0,代表前面的人疯狂吃 就可以让lililalala没得吃 那就是YES

    #include<bits/stdc++.h>
     
    using namespace std;
     
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n,m,i,a[100005],lb=0,ladd=0,l,r;
            cin>>n>>m;
            for(i=0;i<n;i++)
            {
                cin>>a[i];
                if(a[i]>lb)
                {
                    lb=a[i];
                    ladd=i;
                }
            }
            l=m;
            r=m;
            for(i=0;;i=(i+1)%(n))
            {
                if(i==ladd)
                {
                    if(l<=0)
                    {
                        cout<<"YES"<<endl;
                        break;
                    }
                    else
                    {
                        l-=a[i];
                        r-=a[i];
                    }
                }
                else
                {
                    if(r<=0)
                    {
                        cout<<"NO"<<endl;
                        break;
                    }
                    else
                    {
                        r-=1;
                        l-=a[i];
                    }
                }
            }
        }
    }

    F   Black & White

    就是求 包含m个1的最长0串 和 包含m个0的最长1串 的较大值

    在纸上模拟一下或者debug一下就理解了

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    char s[100005];
    int n,m;
    int fun(char ch)
    {
        int cnt=0,ans=0;
        for(int i=0,j=0;i<n;i++){
            if(s[i]==ch){
                if(cnt<m) cnt++;
                else{
                    while(s[j++]!=ch);
                }
            }
            ans=max(ans,i-j+1);
        }
        return ans;
    }
    int main()
    {
        int t; scanf("%d",&t);
        while(t--){
            scanf("%d%d",&n,&m);
            scanf("%s",s);
            printf("%d\n",max(fun('0'),fun('1')));
        }
        return 0;
    }

    G   Truthman or Fakeman

    如果A说B是Truthman 那么A和B是同一个团体

    如果A说B是Fakeman 那么A和B是不同的两个团体

    只要将较大的那个定义为Truthman就好了

    用dfs遍历连通块

    如果一开始设为Truthman的团体较小 那就再dfs一遍取反

    #include<iostream>
    #include<vector>
    #include<cstring>
    using namespace std;
    typedef pair<int,int> pr;
    const int MAX_N=1e5+5;
    int n,m,T;
    int Sum,s,p;
    int res[MAX_N];
    vector<pr> e[MAX_N];
    bool boo[MAX_N];
      
    void DFS(int u,int pre);
    void DFS1(int u,int pre);
    int main()
    {
        ios::sync_with_stdio(false);
        cin>>T;
        while(T--){
            p=1;
            memset(res,-1,sizeof(res));
            memset(boo,0,sizeof(boo));
            cin>>n>>m;
            for(int i=0;i<=n;++i)
                e[i].clear();
            int u,v,w;
            for(int i=0;i<m;++i)
            {
                cin>>u>>v>>w;
                e[u].push_back({v,w});
                e[v].push_back({u,w});
            }
            for(int i=1;i<=n&&p==1;++i)
                if(res[i]==-1){
                    Sum=s=0;
                    boo[i]=true;    res[i]=1;
                    DFS(i,0);
                    if(s+s<Sum)  DFS1(i,0);
                }
            if(p==1){
                for(int i=1;i<=n;++i)
                    cout<<res[i];
                cout<<endl;
            }else   cout<<-1<<endl;
        }
         
        return 0;
    }
      
    void DFS(int u,int pre)
    {
        ++Sum;
        if(res[u]==1)   ++s;
        int v,w;
        for(auto c:e[u])
            if(c.first!=pre){
                if(p==-1)   break;
                v=c.first;  w=c.second;
                if(res[v]!=-1){
                    if((w==1&&res[v]!=res[u])||(w==0&&res[v]+res[u]!=1)){
                        p=-1;   break;
                    }
                }else{
                    if(w==1){
                        if(res[v]!=-1&&res[v]!=res[u])  p=-1;
                        res[v]=res[u];
                    }else{
                        if(res[v]!=-1&&res[v]+res[u]!=1)    p=-1;
                        res[v]=(res[u]+1)%2;
                    }
                    DFS(v,u);
                }
            }
    }
      
    void DFS1(int u,int pre)
    {
        res[u]=(res[u]+1)%2;
        for(auto c:e[u])
            if(c.first!=pre&&!boo[c.first]){
                boo[c.first]=true;
                DFS1(c.first,u);
            }
    }

    H Chat

    分组dp

    题意转化为要求女神生气度为K时能偷懒最长的时间

    dp首先要有代价和价值 代价是鸽女神i个小时 价值就是鸽女神i个小时所能换来的最大时间

    代价是要先求一遍的 具体看代码吧

    #include<bits/stdc++.h>
    
    using namespace std;
    
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n,m,k,w,i,j,vul[205][205],p[205],dp[205][205],it[205];
            memset(vul,0,sizeof(vul));
            memset(p,0,sizeof(p));
            memset(dp,0,sizeof(dp));
            memset(it,0,sizeof(it));
            scanf("%d%d%d",&n,&m,&k);
            int sum=n*m;
            for(i=1;i<=n;i++)
            {
                char a[205]; 
                scanf("%s",a+1);
                for(j=1;j<=m;j++)
                {
                    if(a[j]=='0')
                    p[j]=p[j-1];
                    else
                    {
                        p[j]=p[j-1]+1;
                        it[i]++;
                    }        
                 }
                 vul[i][it[i]]=m;
                 for(j=1;j<=m;j++)
                     for(w=j;w<=m;w++)
                     vul[i][it[i]-(p[w]-p[j-1])]=max(vul[i][it[i]-(p[w]-p[j-1])],m-(w-j+1));
            }
            for(i=1;i<=n;i++)
            for(j=0;j<=it[i];j++)
            for(w=k;w>=j;w--)
            {
                dp[i][w]=max(dp[i][w],dp[i-1][w-j]+vul[i][j]);
            }
            cout<<sum-dp[n][k]<<endl;
        }
    }
  • 相关阅读:
    ES6中的基础语法
    let和const、var
    iframe框架
    ajax
    面试题
    移动端的点击延迟事件
    移动端如何设置字体
    swiper插件以及简介
    第十二章 systemctl管理脚本
    第十一章 awk命令
  • 原文地址:https://www.cnblogs.com/dyhaohaoxuexi/p/10903538.html
Copyright © 2011-2022 走看看