zoukankan      html  css  js  c++  java
  • 暑假N天乐【比赛篇】 —— 2019牛客暑期多校训练营(第六场)

    疯狂摸鱼ing...不想写了。

    以下题解包括:(A B C D E G J)

    比赛地址: https://ac.nowcoder.com/acm/contest/886#question

    【A】 Garbage Classification 水题

    签到题,不说了。

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <bitset>
    #include <cctype>
    #include <cstdio>
    #include <vector>
    #include <string>
    #include <cstdlib>
    #include <cstring>
    #include <fstream>
    #include <iomanip>
    #include <numeric>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const double PI = acos(-1.0);
    const double eps = 1e-6;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    
    const int maxn = 2000+5;
    
    map<char, char> mp;
    char a[maxn], b[maxn];
    
    int main() {
        int t, cas = 1;
        scanf("%d", &t);
        while(t--) {
            mp.clear();
            scanf("%s%s", a, b);
            for(int i = 0; i < 26; i++) {
                mp[i+'a'] = b[i];
            }
            int n = strlen(a);
            int H = 0, W = 0, D = 0;
            for(int i = 0; i < n; i++) {
                if(mp[a[i]] == 'h') {
                    H ++;
                }
                else if(mp[a[i]] == 'd') {
                    D ++;
                }
                else {
                    W ++;
                }
            }
            printf("Case #%d: ", cas++);
            if(H*4 >= n) {
                printf("Harmful
    ");
            }
            else if(H*10 <= n) {
                printf("Recyclable
    ");
            }
            else if(D >= 2*W){
                printf("Dry
    ");
            }
            else {
                printf("Wet
    ");
            }
        }
        return 0;
    }
    

    【B】 Shorten IPv6 Address 模拟

    给定一个长度 128 位的 01 字符串,按照规则进行变换成16进制的 (ipv6) 地址,输出变换后字典序最小的字符串。

    纯大模拟,虽然 (python) 很好写,但我不会啊。代码是现场敲的,极丑将就看吧。

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <bitset>
    #include <cctype>
    #include <cstdio>
    #include <vector>
    #include <string>
    #include <cstdlib>
    #include <cstring>
    #include <fstream>
    #include <iomanip>
    #include <numeric>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const double PI = acos(-1.0);
    const double eps = 1e-6;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    
    const int maxn = 1e3+5;
    
    char s[maxn];
    char str[50][50];
    char str_[50][50];
    struct node {
        int l, r;
        bool operator < (const node& a) const{
            if((r-l+1) == (a.r-a.l+1)) {
                return l > a.l;
            }
            return (r-l+1) > (a.r-a.l+1);
        }
    }p[50];
    
    int main() {
        int t, cas=1;
        scanf("%d", &t);
        while(t--) {
            memset(str, '', sizeof(str));
            memset(str_, '', sizeof(str_));
            memset(s, '', sizeof(s));
            int cnt = 0;
            scanf("%s", s);
            for(int i = 0; i < 128; i+=16) {
                char temp[50];
                int zzz = 0;
                for(int j = i; j < i+16; j+=4) {
                    int sum = 0;
                    int x1 = s[j] - '0';
                    int x2 = s[j+1] - '0';
                    int x3 = s[j+2] - '0';
                    int x4 = s[j+3] - '0';
                    sum = sum + (x1*8 + x2*4 + x3*2 + x4);
    
                    if(sum >= 10) {
                        temp[zzz++] = 'a'+sum-10;
                    }
                    else {
                        temp[zzz++] = '0'+sum;
                    }
                }
                temp[zzz] = '';
                strcpy(str[cnt++], temp);
            }
            for(int i = 0; i < cnt; i++) {
                int flag = 1;
                for(int j = 0; j < 4; j++) {
                    if(str[i][j] != '0') {
                        flag = 0;
                    }
                }
                // cout << flag << endl;
                if(flag) {  // 全 0
                    str_[i][0] = '0';
                }
                else {  // 去前导 0
                    int j;
                    for(j = 0; j < 4; j++) {
                        if(str[i][j] != '0') {
                            break;
                        }
                    }
                    for(int k = j; k < 4; k++) {
                        str_[i][k-j] = str[i][k];
                    }
                    str_[i][4-j] = '';
                }
            }
            int tot = 0;
            int j = 0;
            for(int i = 0; i < cnt; i++) {
                if(strcmp(str_[i], "0") == 0) {
                    for(j = i+1; j < cnt; j++) {
                        if(strcmp(str_[j], "0") != 0) {
                            break;
                        }
                    }
                    p[tot].l = i;
                    p[tot++].r = j-1;
                }
            }
            sort(p, p+tot);
            p[tot].l = inf;
            p[tot++].r = 0;
            char ans[maxn] = {''};
            int MIN = inf;
            for(int k = 0; k < tot; k++) {
                char tep[maxn] = {''};
                int len = p[k].r - p[k].l + 1;
                int ok = 0;
                int res = 0;
                if(len >= 2) {
                    ok = 1;
                }
                for(int i = 0; i < cnt; i++) {
                    if(ok == 0) {
                        int m = strlen(str_[i]);
                        for(int j = 0; j < m; j++) {
                            tep[res++] = str_[i][j];
                        }
                        if(i==cnt-1) {
                            tep[res++] = '';
                        }
                        else {
                            tep[res++] = ':';
                        }
                    }
                    else {
                        if(p[k].l == i) {
                            if(i == 0) {
                                tep[res++] = ':';
                                tep[res++] = ':';
                            }
                            else {
                                tep[res++] = ':';
                            }
                            i = p[k].r;
                            if(i == cnt-1) {
                                tep[res++] = '';
                            }
                            continue;
                        }
                        int m = strlen(str_[i]);
                        for(int j = 0; j < m; j++) {
                            tep[res++] = str_[i][j];
                        }
                        if(i==cnt-1) {
                            tep[res++] = '';
                        }
                        else {
                            tep[res++] = ':';
                        }
                    }
                }
                if(res < MIN) {
                    strcpy(ans, tep);
                    MIN = res;
                }
                else if(res == MIN) {
                    if(strcmp(ans, tep) > 0) {
                        strcpy(ans, tep);
                    }
                }
            }
            printf("Case #%d: ", cas++);
            printf("%s
    ", ans);
        }   
        return 0;
    }
    

    【C】 Palindrome Mouse 回文自动机

    回文自动机套模板。

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <bitset>
    #include <cctype>
    #include <cstdio>
    #include <vector>
    #include <string>
    #include <cstdlib>
    #include <cstring>
    #include <fstream>
    #include <iomanip>
    #include <numeric>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const double PI = acos(-1.0);
    const double eps = 1e-6;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    
    const int maxn = 100005;
    const int N = 26;
    
    ll ans, res;
    
    struct Palindromic_Tree {
        int nxt[maxn][N];   // next指针,next指针和字典树类似,指向的串为当前串两端加上同一个字符构成
        int fail[maxn];     // fail指针,失配后跳转到fail指针指向的节点
        ll cnt[maxn];       // 表示节点i表示的本质不同的串的个数(建树时求出的不是完全的,最后count()函数跑一遍以后才是正确的)
        int num[maxn];      // 表示以节点i表示的最长回文串的最右端点为回文串结尾的回文串个数
        int len[maxn];      // len[i]表示节点i表示的回文串的长度(一个节点表示一个回文串)
        int S[maxn];        // 存放添加的字符
        int last;           // 指向新添加一个字母后所形成的最长回文串表示的节点。
        int n;              // 表示添加的字符个数。
        int p;              // 表示添加的节点个数。
        int vis[maxn];
        int newnode(int l) {// 新建节点
            for(int i = 0; i < N; ++i) 
                nxt[p][i] = 0;
            cnt[p] = 0;
            num[p] = 0;
            len[p] = l;
            vis[p] = 0;
            return p++;
        }
        void init() {   // 初始化
            p = 0;
            newnode(0);
            newnode(-1);
            last = 0;
            n = 0;
            S[n] = -1;  // 开头放一个字符集中没有的字符,减少特判
            fail[0] = 1;
        }
        int get_fail(int x) {   // 和KMP一样,失配后找一个尽量最长的
            while(S[n-len[x]-1] != S[n]) x = fail[x];
            return x;
        }
        void add(int c) {
            c -= 'a';
            S[++n] = c;
            int cur = get_fail(last);   // 通过上一个回文串找这个回文串的匹配位置
            if(!nxt[cur][c]) {     // 如果这个回文串没有出现过,说明出现了一个新的本质不同的回文串
                int now = newnode(len[cur]+2);     // 新建节点
                fail[now] = nxt[get_fail(fail[cur])][c];    // 和AC自动机一样建立fail指针,以便失配后跳转
                nxt[cur][c] = now;
                num[now] = num[fail[now]] + 1;
            }
            last = nxt[cur][c];
            cnt[last] ++;
        }
        void dfs(int x) {
            stack<int> s;
            int y = fail[x];
            while(y > 1 && vis[y] == 0) {
                res ++;
                s.push(y);
                vis[y] = 1;
                y = fail[y];
            }
            if(x > 1) {
                ans += res;
                vis[x] = 1;
                res ++;
            }
            for(int i = 0; i < 26; i++) {
                if(nxt[x][i]) {
                    dfs(nxt[x][i]);
                }
            }
            if(x > 1) {
                vis[x] = 0;
                res --;
            }
            y = x;
            while(!s.empty()) {
                res --;
                vis[s.top()] = 0;
                s.pop();
            }
        }
    }T;
    
    int main() {
        string a;
        int t;
        int cas = 1;
        cin >> t;
        while(t--) {
            cin >> a;
            T.init();
            int len = a.size();
            for(int i = 0; i < len; i++)
                T.add(a[i]);
            res = ans = 0;
            T.dfs(0);
            T.dfs(1);
            cout << "Case #" << cas++ << ": ";
            cout << ans << endl;
        }
    }
    

    【D】 Move 思维/二分

    虽然是数据水所以二分过了,但是我懒得写正解,就这样。

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <bitset>
    #include <cctype>
    #include <cstdio>
    #include <vector>
    #include <string>
    #include <cstdlib>
    #include <cstring>
    #include <fstream>
    #include <iomanip>
    #include <numeric>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const double PI = acos(-1.0);
    const double eps = 1e-6;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    const int maxn = 1e3+5;
     
    int n, k;
    int a[maxn];
    int sk[maxn];
    multiset<int> s;
     
    int solve(int x) {
        multiset<int> temp;
        temp = s;
        for(int i = 1; i <= k; i++) {
            int sum = x;
            while(sum>0) {
                auto it = temp.upper_bound(sum);
                if(it == temp.begin()) {
                    break;
                }
                it--;          
                sum -= (*it);
                temp.erase(it);
            }      
            if(temp.size() == 0) {
                return 1;
            }
        }
        return 0;
    }
     
    int main() {
        int t, cas = 1;
        scanf("%d", &t);
        while(t--) {
            s.clear();
            scanf("%d%d", &n, &k);
            for(int i = 1; i <= n; i++) {
                scanf("%d", &a[i]);
                s.insert(a[i]);
            }
            int l = 1, r = 1000*1000+5;
            int ans = 1;
            while(l <= r) {
                int mid = (l+r) >> 1;
                int res = solve(mid);
                if(res == 1) {
                    ans = mid;
                    r = mid-1;
                }
                else {
                    l = mid+1;
                }
            }
            for(int i = max(0, ans-100); i <= ans; i++) {
                if(solve(i)) {
                    printf("Case #%d: ", cas++);
                    printf("%d
    ", i);
                    break;
                }
            }
        }
        return 0;
    }
    

    【E】 Androgynos 构造

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <bitset>
    #include <cctype>
    #include <cstdio>
    #include <vector>
    #include <string>
    #include <cstdlib>
    #include <cstring>
    #include <fstream>
    #include <iomanip>
    #include <numeric>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const double PI = acos(-1.0);
    const double eps = 1e-6;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    
    const int maxn = 2e3+5;
    
    int mp[maxn][maxn];
    int ans[maxn];
    int n;
    
    int main() {
        int t, cas = 1;
        scanf("%d", &t);
        while(t--) {
            scanf("%d", &n);
            printf("Case #%d: ", cas++);
            if(n % 4 != 0 && n % 4 != 1) {
                printf("No
    ");
            }
            else {
                printf("Yes
    ");
                int k = n / 4;
                memset(mp, 0, sizeof(mp));
                /*
                    团 1  独立集 2  独立集 3  团 4
                */
                // 团 1 内部
                for(int i = 1; i <= k; i++) {
                    for(int j = 1; j <= k; j++) {
                        if(i != j) {
                            mp[i][j] = mp[j][i] = 1;
                        }
                    }
                }
                // 团 1 --> 独立集 2
                for(int i = 1; i <= k; i++) {
                    for(int j = k+1; j <= 2*k; j++) {
                        mp[i][j] = mp[j][i] = 1;
                    }
                }
                // 独立集 2 --> 独立集 3
                for(int i = k+1; i <= 2*k; i++) {
                    for(int j = 2*k+1; j <= 3*k; j++) {
                        mp[i][j] = mp[j][i] = 1;
                    }
                }
                // 独立集 3 --> 团 4
                for(int i = 2*k+1; i <= 3*k; i++) {
                    for(int j = 3*k+1; j <= 4*k; j++) {
                        mp[i][j] = mp[j][i] = 1;
                    }
                }
                // 团 4 内部
                for(int i = 3*k+1; i <= 4*k; i++) {
                    for(int j = 3*k+1; j <= 4*k; j++) {
                        if(i != j) {
                            mp[i][j] = mp[j][i] = 1;
                        }
                    }
                }
                // 1 2 3 4 ---> ans[i] = 2 4 1 3 
                for(int i = 1; i <= k; i++) {
                    ans[i] = i+k;
                    ans[i+k] = i+3*k;
                    ans[i+2*k] = i;
                    ans[i+3*k] = i+2*k;
                }
                // 多出来的点连向两个团 1 4 即可
                if(n % 4 == 1) {
                    for(int i = 1; i <= k; i++) {
                        mp[i][n] = mp[n][i] = 1;
                    }
                    for(int i = 3*k+1; i <= 4*k; i++) {
                        mp[i][n] = mp[n][i] = 1;
                    }
                    ans[n] = n;
                }
                for(int i = 1; i <= n; i++) {
                    for(int j = 1; j <= n; j++) {
                        printf("%d", mp[i][j]);
                    }
                    printf("
    ");
                }
                for(int i = 1; i <= n; i++) {
                    printf("%d%c", ans[i], i==n?'
    ':' ');
                }
            }
        }
        return 0;
    }
    

    【G】 Is Today Friday? 暴力

    #include <map>
    #include <set>
    #include <list>
    #include <cmath>
    #include <ctime>
    #include <deque>
    #include <stack>
    #include <queue>
    #include <bitset>
    #include <cctype>
    #include <cstdio>
    #include <vector>
    #include <string>
    #include <cstdlib>
    #include <cstring>
    #include <fstream>
    #include <iomanip>
    #include <numeric>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const double PI = acos(-1.0);
    const double eps = 1e-6;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9 + 7;
    
    const int maxn = 1e5+5;
    
    int n;
    string str[maxn];
    int ord[10];
    
    int check(int x) {
        int year = ord[str[x][0]-'A']*1000 + ord[str[x][1]-'A']*100 + ord[str[x][2]-'A']*10 + ord[str[x][3]-'A'];
        int month = ord[str[x][5]-'A']*10 + ord[str[x][6]-'A'];
        int day = ord[str[x][8]-'A']*10 + ord[str[x][9]-'A'];
        int d_max;
        if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) {
            d_max = 31;
        }
        else if(month==4 || month==6 || month==9 || month==11) {
            d_max = 30;
        }
        else if(month==2 && ((year%4==0 && year%100!=0) || year%400==0)) {
            d_max = 29;
        }
        else {
            d_max = 28;
        }
        if(year<1600 || year>9999 || month<1 || month>12 || day<1 || day>d_max) {
            return 0;
        }
        if(month==1 || month==2) {
            year--;
            month += 12;
        }
        int w = (day + 2*month + 3*(month+1)/5 + year + year/4 - year/100 + year/400) % 7 + 1;
        if(w == 5) {
            return 1;
        } 
        return 0;
    }
    
    int main() {
        int t, cas = 1;
        scanf("%d", &t);
        while(t--) {
            for(int i = 0; i < 10; i++) {
                ord[i] = i;
            }
            scanf("%d", &n);
            for(int i = 1; i <= n; i++) {
                cin >> str[i];
            }
            sort(str+1, str+1+n);
            n = unique(str+1, str+1+n) - (str+1);
            int ok = 0;
            do {
                ok = 1;
                for(int i = 1; i <= n; i++) {
                    if(check(i) == 0) {
                        ok = 0;
                        break;
                    }
                }
                if(ok) {
                    break;
                }
            }while(next_permutation(ord, ord+10));
            printf("Case #%d: ", cas++);
            if(ok == 0) {
                printf("Impossible
    ");
            }
            else {
                for(int i = 0; i < 10; i++) {
                    printf("%d", ord[i]);
                }
                printf("
    ");
            }
        }
        return 0;
    }
    

    【J】 Upgrading Technology 贪心

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
     
    typedef long long ll;
    const int maxn=1019;
    const ll INF = 1ll*(1e9)*(1e5);
    ll a[maxn][maxn],d[maxn];
    ll pre[maxn][maxn];
    ll P[maxn];
    ll tail[maxn];
    int n,m;
    ll minn;
    ll ans1,ans2,minj;
     
    int main(){
        int T;
        scanf("%d",&T);
        int kase=1;
        while(T--){
            scanf("%d%d",&n,&m);
            memset(pre,0,sizeof(pre));
            memset(P,0,sizeof(P));
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    scanf("%lld",&a[i][j]);
                }
            }
            for(int i=1;i<=m;i++){
                scanf("%lld",&d[i]);
            }
             
            for(int i=1;i<=m;i++){
                for(int j=1;j<=n;j++){
                    P[i]-=a[j][i];
                }
                P[i]=P[i-1]+P[i]+d[i];
            }
            memset(tail,0,sizeof(tail));
            //tail[n]!
            ll ans=P[m];
            for(int i=m-1;i>=0;i--){
                int flag=0;minn=-INF;
                for(int j=1;j<=n;j++){
                    if(tail[j]+a[j][i+1]<=0){
                        tail[j]+=a[j][i+1];
                        P[i]-=tail[j];
                        if(minn<=tail[j]){
                            minn=tail[j];
                            minj=j;
                        }
                    }
                    else{
                        tail[j]=0;
                        flag=1;
                    }
                }
                if(!flag){
                    tail[minj]=0;
                    P[i]+=minn;
                }
                ans=max(ans,P[i]);
            }
            if(ans<0) ans=0;
            printf("Case #%d: %lld
    ",kase++,ans);
        }
    }
    
  • 相关阅读:
    extel操作
    postman 使用post方式提交参数值
    json_encode 转化数组时,中文不转义出现乱码的解决方法
    csnd 不好使,所以我来博客园了
    Nodejs 之Ajax的一个实例(sql单条件查询&并显示在Browser端界面上)
    JS 之JSON
    Nodejs sql模块及模块化思想
    Nodejs之Ajax
    Nodejs 之express框架的应用---简单的登录界面
    Nodejs 入门 12-28
  • 原文地址:https://www.cnblogs.com/Decray/p/11327795.html
Copyright © 2011-2022 走看看