zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第六场)

     // 比赛链接:https://ac.nowcoder.com/acm/contest/886#question

     // 又是自闭的一下午,今天我爆零了T_T
    
     // 开始直奔B题,一看感觉很容易,进制转换然后处理一下输出就完事了,签到题吧
    
     // 喝完药就开始码,队友说A题签到,然后A了。我继续,看榜感觉不太对劲,B通过率真低。
    
     // 写着突然B题更新,没问题,描述更清晰了而已,没有曲解题意,继续写。调好了样例,直接交。
    
     // WA1 。。。WA2。。。 WA3。。。甩锅不写了
    
     // 吴先生在写D题写半天了,我瞅一眼不就二分,我也写好了,互相交全WA。
    
     // 吴先生一看输出都写错了,没敢交了。我自闭。
    
     // 剩下时间看了G,想到那个求星期的公式,然后构思怎么枚举,断断续续写了快一个小时。
    
     // 脑子有点不清晰,不知道用循环写还是dfs搜,反反复复,又觉得复杂度太高,怎么都要T。
    
     // 陷入B-D-G死循环。
    View Code

     

    A - Garbage Classification

    题意:给了一堆垃圾,判断它是有害垃圾/可回收垃圾/干垃圾/湿垃圾。两行输入,一行字符串表示垃圾,另一行代表每个小写字母的垃圾种类。

    题解:模拟。真正的签到题。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    char s[3010],t[30];
    int main()
    {
        int T,cas=0;cin>>T;
        while(T--)
        {
            printf("Case #%d: ",++cas);
            cin>>s>>t;
            int h=0,d=0,w=0;
            int ls = strlen(s);
            for(int i=0;i<ls;++i)
            {
                if(t[s[i]-'a']=='h')
                    h++;
                else if(t[s[i]-'a']=='d')
                    d++;
                else if(t[s[i]-'a']=='w')
                    w++;
            }
    
            if(4*h>=ls)
                puts("Harmful");
            else if(h*10<=ls)
                puts("Recyclable");
            else if(d>=2*w)
                puts("Dry");
            else
                puts("Wet");
                 
        }
        return 0;
    }
    View Code

    B - Shorten IPv6 Address  (补)

    题意:给一段ipv6的二进制地址,让你转成16进制输出,如果有至少两段的连续0,可以省写为两个冒号::,但只能用一次。求缩写最短的形式中字典序最小的答案。

    思路:字典序最小,首先保证串最短,那么找到连续0最长的部分改写为【::】的即可,长度相等选择靠后的。

    坑:首尾位置与中间位置加上【::】的长度不相同。。。

    题解:官方题解不知道在说什么,看了直播也没听懂在讲什么,有一条弹幕给了一个【将最长的靠后0串改为::】的反例,我百思不得其解,正准备让电脑跑一下他们的字典序大小,写一起才看明白了:

    【::】放在开头或结尾长度会比放中间多一位!!!

    AC代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
      
    char s[130];
    int v[10];
    int z[10];
    int main() {
        int T; cin>>T; int t = 0;
        while(t<T) {
            scanf("%s", s+1);
            memset(z, 0, sizeof(z));
             
            printf("Case #%d: ", ++t);
            int value = 0;
            for(int i=1;s[i];i++) {
                value = value*2 + (s[i]=='1');
                if(i%16==0) {
                    v[i/16] = value;
                    value = 0;
                }
            }
              
             
            for(int i=8;i>=1;i--) {
                if(v[i]==0) {
                    z[i] = z[i+1] + 1;
                    z[i+1] = 0;
                }
                else
                    z[i] = 0;
            }
            if(z[1]==8) {
                printf("::
    ");
                continue;
            }
              
            int len = 0, cnt = 0;
            int maxLen = -1, pos = -1;
             
            for(int i=1;i<=8;i++) {
                if(v[i]==0) {
                    ++len;
                } else {
                    if(len>=2) {
                        ++cnt;
                        if(maxLen<=len) {
                            maxLen = len;
                            pos = i-1;
                        }
                    }
                    len = 0;
                }
                if(i==8 && len>=2) {
                    ++cnt;
                    if(maxLen<len || maxLen==len && maxLen==z[1] && cnt<=2) {
                        maxLen = len;
                        pos = i;
                    }
                }
            }
            if(cnt<1) {
                for(int i=1;i<=8;i++) {
                    printf("%0x%c", v[i], i==8?'
    ':':');
                }
            } else
                {
                int k = pos;
                while(v[k]==0 && k>=1) k--;
                if(k==0) printf(":");
                for(int i=1;i<=k;i++) {
                    printf("%0x:", v[i]);
                }
                printf(":");
      
                if(pos==8) {
                    printf("
    ");
                    continue;
                }
                for(int i=pos+1;i<=8;i++)
                    printf("%0x%c", v[i], i==8?'
    ':':');
            }
              
        }
          
        return 0;
    }
    View Code

    D - Move(补)

    题意:有n个物品,每个体积vi,给你k个相同容积的箱子装,装箱按照从大到小顺序直到塞满或装不下为止。问箱子的最小容积。

    思路:不能二分。。。因为箱子容积和k之间不满足单调性(即使经验上一致,也没找到反例)

    官方反例:

    n = 15  k = 5

    39 39 39 39 39 60 60 60 60 60 100 100 100 100 100

    199为合法的答案,但200不是,201也不是。

    AC代码:(把二分改成暴力从 max(totV/k, maxV)开始枚举就够了。。)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
       
    int v[1010], n, k;
    bool vis[1010];
    bool ok(int V) {
        int res = 0, cnt = 0;
        int now = V;
        memset(vis, 0, sizeof(vis));
        while(cnt<n) {
            for(int i=n;i>=1&&now;i--)
                if(!vis[i] && now>=v[i]) {
                    now -= v[i];
                    vis[i] = 1;
                    ++cnt;
                }
            res++;
            now = V;
        }
        return res<=k;
           
    }
       
    int main() {
        int T; cin>>T; int t = 0;
        while(t<T) {
            scanf("%d %d", &n, &k);
            int totV = 0, maxV = 0;
            for(int i=1;i<=n;i++) {
                scanf("%d", &v[i]);
                totV += v[i];
                maxV = max(maxV, v[i]);
            }
            sort(v+1, v+1+n);
               
            int ans = max(maxV, (totV+k-1)/k);
            while(!ok(ans)) {
                ++ans;
            }
             
            printf("Case #%d: %d
    ", ++t, ans);
        }
           
        return 0;
    }
    View Code

    G - Is Today Friday?(补)

    题意:给你n个只包含A~J大写字母的yyyy/mm/dd形式的加密字符串,求解A~J使日期都是星期五。(n<=10000)

    思路:每个日期枚举的规模在:2(月开头数字) * 4(日开头数字)  * 8 * 7 * 6 * 5 * 4 * 3 =  1.6e5,然后再判断n个是否满足。

    题目数据sb。。。知道蔡勒公式再暴力枚举就完事了。。。关键在于去重。。。

    sort(date+1, date+1+n); 
    n = unique(date+1, date+1+n) - (date+1);

    AC代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
     
    struct node {
        char y[5];
        char m[3];
        char d[3];
        string s;
        bool operator<(const node& a) {
            return s < a.s;
        }
        bool operator==(const node& a) {
            return s == a.s;
        }
    }date[100100];
     
    int n;
     
    bool valid(int y, int m, int d) {
        if(m>12 || d>31) return false;
        if(m==2) {
            if(d<=28) return true;
            else if(d>29) return false;
            return y%400==0 || (y%4==0 && y%100!=0);
        }
        if(d==31) {
            switch(m) {
    //            case 1: case 3: case 5: case 7: case 8:
    //            case 10: case 12: return true;
                case 4: case 6: case 9: case 11: return false;
                return true;
            }
        }
        return true;
    }
    bool check(int y, int m, int d) { // 蔡勒公式 w为星期,0表示星期天
        if(m==1 || m==2) m += 12, --y;
         
        int c = y / 100;
        y = y - c * 100;
        int w = y + y / 4 + c / 4 - 2 * c + 26 * (m + 1) / 10 + d - 1;
        w = (w%7+7)%7;
        return w==5;
    }
     
    bool vis[10], flag;
    int dic[10];
    int month_First[10];
    int day_First[10];
     
    void dfs(int k) {
        if(k>9) {
            for(int i=1;i<=n;i++) {
                int year = dic[date[i].y[0]-'A']*1000 + dic[date[i].y[1]-'A']*100 +
                    dic[date[i].y[2]-'A']*10 + dic[date[i].y[3]-'A'];
                if(year<1600) return;
                 
                int mon = dic[date[i].m[0]-'A']*10 + dic[date[i].m[1]-'A'];
                int day = dic[date[i].d[0]-'A']*10 + dic[date[i].d[1]-'A'];
                if(!valid(year, mon, day) || !check(year, mon, day)) return;
            }
            flag = true;
            for(int i=0;i<=9;i++) {
                printf("%d", dic[i]);
            }
            printf("
    ");
            return;
        }
         
        for(int i=0;i<=9;i++) {
            if(i>2 && month_First[k]) break;
            if(i>3 && day_First[k]) break;
             
            if(!vis[i]) {
                dic[k] = i;
                vis[i] = 1;
                 
                if(!flag)
                    dfs(k+1);
                 
                vis[i] = 0;
                dic[k] = -1;
            }
        }
    }
     
     
     
    int main() {
        int T; cin>>T; int t=0;
        while(t<T) {
            scanf("%d", &n);
            memset(month_First, 0, sizeof(month_First));
            memset(day_First, 0, sizeof(day_First));
             
            for(int i=1;i<=n;i++) {
                scanf("%4s/%2s/%2s", date[i].y, date[i].m, date[i].d);
                date[i].s =  date[i].y;
                date[i].s += date[i].m;
                date[i].s += date[i].d;
                 
                month_First[date[i].m[0]-'A'] = 1;
                day_First[date[i].d[0]-'A'] = 1;
            }
             
            sort(date+1, date+1+n);
            n = unique(date+1, date+1+n) - (date+1);
     
            printf("Case #%d: ", ++t);
            flag = 0;
            dfs(0); 
     
          if(!flag) printf("Impossible
    ");
             
        }
         
        return 0;
    }
    View Code

    J - Upgrading Technology


        (未完待补。。。) 

  • 相关阅读:
    3. Image Structure and Generation
    STM32F103
    10.2 External interrupt/event controller (EXTI)
    10.1 Nested vectored interrupt controller (NVIC) 嵌套矢量中断控制器
    ibatis 使用 in 查询的几种XML写法
    文字纵向打印
    oracle每天清理归档日志
    使用语句查询mssql死锁
    Xml序列化UTF-8格式错误
    Nginx的优点
  • 原文地址:https://www.cnblogs.com/izcat/p/11296827.html
Copyright © 2011-2022 走看看