zoukankan      html  css  js  c++  java
  • GCJ2016 round1A

    三天不写手生,半年不写成渣。。

    以翔一般的手速写翔一般的代码,趴。还是要经常写写。

    //今年三题都对都不一定能进下一轮,= = 简直手速赛,比起去年两题+第三题小数据就能混进round2

    Problem A. The Last Word

    给一个长度为1000的字符串S和一个空串T,从左到右一个个取出S里的字符,放进T中,放进T时可以放在最左边或最右边。

    e.g. for S = CAB,

    • put the A before C to form AC, then put the B before AC to form BAC
    • put the A before C to form AC, then put the B after AC to form ACB
    • put the A after C to form CA, then put the B before CA to form BCA
    • put the A after C to form CA, then put the B after CA to form CAB

    问所有可能的T里,字典序最大的是哪一个。

    solution:简单的贪心策略,对于每一个要放的字符c,如果它大于等于T串中最左边的字符,则将其放在T的左边,否则放在右边。

    code:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N  = 2005;
    char str[N];
    
    int main(){
        freopen("A-large.in", "r", stdin);
        freopen("large.out", "w", stdout);
        int TC, tc;
        scanf("%d", &TC);
        for(tc = 1; tc <= TC; tc++){
            scanf("%s", str);
            int n = strlen(str);
            deque<char>dq;
            char leftest = 0;
    
            for(int i = 0; i < n; i++){
                if(str[i] >= leftest){
                    dq.push_front(str[i]);
                    leftest = str[i];
                }else {
                    dq.push_back(str[i]);
    
                }
            }
            printf("Case #%d: ", tc);
            while(!dq.empty()){
                printf("%c", dq.front());
                dq.pop_front();
            }
            printf("
    ");
        }
        return 0;
    }
    View Code

    Problem B. Rank and File

    这道题很有意思,有一个N*N的矩阵,(N<=50),保证每行严格递增,每列严格递增。

    将每行列出来,每列列出来,可以得到2N个数字序列。

    现在把这些序列打乱(也就是说,不知道每一个序列是行序列还是列序列,也不知道他们是第几行or第几列),从中删除一个序列。

    给出剩下的(2*N-1)个序列,问删除的那个序列长什么样子。

    solution:一开始想的是如何花样复原矩阵,想了好久想不出来。

    换个思路,对于2*N个数字序列,每个矩阵中的数字一定出现偶数次(行一次,列一次),因此,对于2*N-1个序列,他们中只出现奇数次的数就是删掉的序列里的数。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N  = 2600;
    int cnt[N];
    
    int main(){
            freopen("A-large.in", "r", stdin);
        freopen("large.out", "w", stdout);
        int TC, tc;
        scanf("%d", &TC);
        for(tc = 1; tc<= TC; tc++){
            int n;
            int x;
            scanf("%d", &n);
            vector<int>ans;
            int m = 2 * n - 1;
            memset(cnt, 0, sizeof(cnt));
            for(int i = 1; i <= m; i++){
                for(int j = 1; j <= n; j++){
                    scanf("%d", &x);
                    cnt[x] ++;
                }
            }
            for(int i = 1; i <= 2500; i++){
                if(cnt[i] & 1){
                    ans.push_back(i);
                }
            }
            printf("Case #%d:", tc);
            for(int i = 0; i < ans.size(); i++){
                printf(" %d", ans[i]);
            }
            printf("
    ");
    
        }
    return 0;
    }
    View Code

    Problem C. BFFs

    有N个人(3 ≤ N ≤ 1000.),每个人都有一个喜欢的人。(不一定互相喜欢)

    现在需要从中挑出一些人,让他们坐成一个圈,使得每个人喜欢的人能够坐在他的左边或者右边。

    问最多能挑出多少人。

    solution:如果看成一个图的话,这是一个每个点出度都为1的图。

    很显然的,对于图中的一个环,能够符合上述条件。挑出的最大(长?)的环是符合条件的一个候选答案,设为maxloop。

    但还有一种构造,注意到有一种特别的环,A喜欢B,B喜欢A。对于这种长度为2的环,可以安排AB坐在一起,接下来A旁边坐喜欢A的C,再坐喜欢C的D,依次类推。。同理B。

    设上述这种长度为2的环带两条链(当然也可能没有链或一条链)为X。

    有出度为1这个限制,最大环中不能加人。所有的X可以拼接(大概如图这样拼)

    因此答案为max{len(maxloop),sum(len(Xi))}

    因此首先(代码中第一次bfs)找出这个图中的最大的环,BFS DFS都可以,注意的点是,一般是枚举一个点然后去找他左右能通向的点,一路标记,如果标到了已经有深度的点就看深度(距离?dis),但是可能出现找到一个其他的点所标记的点,所以找环的时候一定要保证找到的环上的点是同一个祖先找出来的,方法有很多,我写得挫请不要借鉴。

    然后(代码中第二次bfs)对于所有的点,也要记录反向边。对所有长度为2的环,对环两端的点分别沿反向边找到最远的点,链长就是len(Xi)

    对两个求最大值即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    
    const int N  = 1005;
    int head[N];
    
    struct point{
        int x, y,  next;
        point(){};
        point(int _x, int _y, int _next){
            x = _x, y = _y, next = _next;
        }
    }p[N];
    struct favpair{
        int x, y;
        favpair(){};
        favpair(int _x, int _y){
            x = _x, y = _y;
        };
    };
    int ans;
    int fav[N];
    int no;
    int vis[N], dis[N];
    vector<int>backedge[N];
    void init(){
        memset(head, -1, sizeof(head));
        memset(vis, 0, sizeof(vis));
        memset(dis, 0, sizeof(dis));
        fill(backedge, backedge + N, vector<int>() );
        no = 0; ans = 0;
    }
    void add(int x, int y){
        p[no] = point(x, y, head[x]);   head[x]=no++;
    }
    
    void bfs(int x){
        int s = x;
        queue<int>q;
        q.push(x);
        vis[x] = true;
        bool inthisloop[N];
        memset(inthisloop, 0, sizeof(inthisloop));
        while(!q.empty()){
            x = q.front();  q.pop();
            for(int i = head[x]; i != -1; i = p[i].next){
                int y = p[i].y;
                if(dis[y])  continue;
                inthisloop[y] = true;
                if(!vis[y]){
                    vis[y] = true;
                    q.push(y);
                }
            }
        }
        dis[s] = 1;
        q.push(s);
        while(!q.empty()){
            x = q.front();  q.pop();
            for(int i = head[x]; i != -1; i = p[i].next){
                int y = p[i].y;
                if(!inthisloop[y]) continue;
                //printf("?y:%d %d
    ", y, dis[y]);
                if(dis[y] == 0){
                    dis[y] = dis[x] + 1;
                    q.push(y);
                }else{
                    //printf("%d %d %d %d %d
    ",x, y, dis[x], dis[y], dis[x] - dis[y] + 1);
                    ans = max(ans, dis[x] - dis[y] + 1);
                }
            }
        }
        //printf("!%d
    ", ans);
    }
    
    int bfs(int x, int y){
        queue<int>q;
        q.push(x);
        dis[x] = 1;
        int len = 1;
        while(!q.empty()){
            x = q.front();  q.pop();
            for(int i = 0; i < backedge[x].size(); i++){
                int st = backedge[x][i];
                if(st == y) continue;
                dis[st] = dis[x] + 1;
                len = max(dis[st], len);
                q.push(st);
            }
        }
        return len;
    }
    int main(){
                freopen("A-large.in", "r", stdin);
        freopen("large.out", "w", stdout);
        int tc, TC;
        scanf("%d", &TC);
        for(tc = 1;  tc <= TC; tc++){
            int n;
            scanf("%d", &n);
            init();
    
            for(int i = 1; i <= n; i++){
                scanf("%d", &fav[i]);
                add(i, fav[i]);
                backedge[fav[i]].push_back(i);
            }
            for(int i = 1; i <= n; i++){
                if(!vis[i]){
                    bfs(i);
                }
            }
            vector<struct favpair>favp;
            favp.clear();
            for(int i = 1; i <= n; i++){
                if(fav[fav[i]] == i){
                    if(fav[i] > i)
                        favp.push_back(favpair(i, fav[i]));
                }
            }
            memset(dis, 0, sizeof(dis));
            int temp = 0;
            for(int i = 0; i < favp.size(); i++){
                int x = favp[i].x;  int y = favp[i].y;
                temp += bfs(x, y);
               // printf("%d %d
    ", x, temp);
                temp += bfs(y, x);
            }
    
            printf("Case #%d: %d
    ",tc, max(ans, temp));
    
        }
        return 0;
    }
    View Code
  • 相关阅读:
    聊聊高并发系统之限流特技
    Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
    密码技术(图解密码技术的学习总结)
    Nginx配置
    Nginx与浏览器缓存
    JAVA类加载和初始化
    [TimLinux] JavaScript 模态框可拖动功能实现——节流版
    [TimLinux] JavaScript 模态框可拖动功能实现——原始版
    [TimLinux] Python3 Coverity zeep/SOAP 库使用示例
    [TimLinux] Vue.js -- Day02 -- 第一个示例
  • 原文地址:https://www.cnblogs.com/bbbbbq/p/5408538.html
Copyright © 2011-2022 走看看