• ACM学习历程—Codeforces Round #354 (Div. 2)


    http://codeforces.com/contest/676

    allzysyz学弟和hqwhqwhq的邀请下,打了我的第三场CF。。。

    毕竟在半夜。。所以本来想水到12点就去睡觉的。。。结果一下次过了三题,发现第四题是个bfs,就打到了12:30.。。。BC貌似是没有了,不知道后面还会不会有,最近就打CF为主吧。。

     

    A题:

    http://codeforces.com/problemset/problem/676/A

    应该算是比较水吧。没有什么坑点。直接枚举最大值在最左最右侧和最小值在最左最右侧四种情况。

     

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <vector>
    #include <string>
    #define LL long long
    
    using namespace std;
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        //freopen("test.out", "w", stdout);
        int n, t, indexone, indexn;
        while (scanf("%d", &n) != EOF)
        {
            for (int i = 0; i < n; ++i)
            {
                scanf("%d", &t);
                if (t == 1) indexone = i;
                if (t == n) indexn = i;
            }
            printf("%d
    ", max(max(indexone, n-1-indexone), max(indexn, n-1-indexn)));
        }
        return 0;
    }
    View Code

     

    B题:

    http://codeforces.com/problemset/problem/676/B

    ccpc热身赛一题的简化版,首先我可以把所有的酒强行先倒入第一杯,然后让它一层一层往下流。暴力模拟一遍就可以了。上一层的第i杯,会流入下一层的第i杯和第i+1杯。

     

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <vector>
    #include <string>
    #define LL long long
    
    using namespace std;
    
    double a[2][10000];
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        //freopen("test.out", "w", stdout);
        int n, t, ans;
        double tmp;
        while (scanf("%d%d", &n, &t) != EOF)
        {
            bool flag;
            ans = 0;
            a[1][1] = t;
            for (int i = 1; i <= n; ++i)
            {
                memset(a[(i+1)%2], 0, sizeof(a[(i+1)%2]));
                flag = true;
                for (int j = 1; j <= i; ++j)
                {
                    if (a[i%2][j] >= 1)
                    {
                        tmp = a[i%2][j]-1;
                        ans++;
                        a[(i+1)%2][j] += tmp/2.0;
                        a[(i+1)%2][j+1] += tmp/2.0;
                        flag = false;
                    }
                }
                if (flag) break;
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code

    C题:

    http://codeforces.com/problemset/problem/676/C

    当时比较直接的想法就先求出把前i段都变成同样字符的代价的所有前缀和suma, sumb。这样就可以求解任意区间变成同样字符的代价了。

    然后枚举区间左值,二分区间右值。就可以求解了。这样的复杂度是nlogn

    但是考虑到区间右值其实具有单调性。于是我可以从后往前遍历区间左值,那么区间右值要么不变,要么是上一次的位置往前移动。于是用两个指针就可以2n时间内完成了。

     

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <vector>
    #include <string>
    #define LL long long
    
    using namespace std;
    
    const int maxN = 100005;
    int n, k;
    int suma[maxN], sumb[maxN];
    char str[maxN];
    
    void input()
    {
        scanf("%s", str);
        suma[0] = sumb[0] = 0;
        for (int i = 0; i < n; ++i)
        {
            if (str[i] == 'a')
            {
                suma[i+1] = suma[i];
                sumb[i+1] = sumb[i]+1;
            }
            else
            {
                suma[i+1] = suma[i]+1;
                sumb[i+1] = sumb[i];
            }
        }
    }
    
    int getLen(int from)
    {
        int ans, lt = from, rt = n, mid;
        while (lt+1 < rt)
        {
            mid = (lt+rt)>>1;
            if (suma[mid]-suma[from-1] > k) rt = mid;
            else lt = mid;
        }
        if (suma[rt]-suma[from-1] <= k) ans = rt-from+1;
        else ans = lt-from+1;
    
        lt = from; rt = n;
        while (lt+1 < rt)
        {
            mid = (lt+rt)>>1;
            if (sumb[mid]-sumb[from-1] > k) rt = mid;
            else lt = mid;
        }
        if (sumb[rt]-sumb[from-1] <= k) ans = max(ans, rt-from+1);
        else ans = max(ans, lt-from+1);
        return ans;
    }
    
    void work()
    {
        int ans = 0;
        for (int i = 1; i <= n; ++i)
            ans = max(ans, getLen(i));
        printf("%d
    ", ans);
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        //freopen("test.out", "w", stdout);
        while (scanf("%d%d", &n, &k) != EOF)
        {
            input();
            work();
        }
        return 0;
    }
    View Code

     

    D题:

    http://codeforces.com/problemset/problem/676/D

    这题是个bfs,比较容易看出来。首先我设置一个二进制状态1111,四位,最高位表示上方有门,第二位表示右方有门,第一位表示下方有门,最低位第0位表示左方有门。

    然后写个swtich,把map中所有的字符映射到二进制状态。

    然后就是bfs了。

    bfs带有三个状态x,y,statexy即坐标,state表示经过了几次旋转。

    然后就是瞎几把搜了。。。

    第一种情况(state+1)%4

    第二种情况便是上下左右搜,代码我是直接复制粘贴,所以只看往上的情况。

    首先这种状态下必须上方有门,而且上面的格子下方有门。

    对于上方有门,由于是顺时针旋转,也就是mp的映射二进制位最高位在逆时针旋转后是1。而这个逆时针旋转就是(3+state)%4这一位了。代码里可以看出来。

     

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <queue>
    #include <vector>
    #include <string>
    #define LL long long
    
    using namespace std;
    
    //up right down left
    int get(char ch)
    {
        switch (ch)
        {
            case '+': return 15;
            case '-': return 5;
            case '|': return 10;
            case '^': return 8;
            case '>': return 4;
            case '<': return 1;
            case 'v': return 2;
            case 'L': return 14;
            case 'R': return 11;
            case 'U': return 7;
            case 'D': return 13;
            case '*': return 0;
        }
    }
    
    bool judge(int p, int index)
    {
        for (int i = 0; i < index; ++i)
            p >>= 1;
        return p&1;
    }
    
    const int maxN = 1005;
    int n, m, fromx, fromy, tox, toy;
    char mp[maxN][maxN];
    int s[maxN][maxN][5];
    
    void input()
    {
        memset(mp, '*', sizeof(mp));
        memset(s, -1, sizeof(s));
        for (int i = 1; i <= n; ++i)
        {
            scanf("%s", mp[i]+1);
            mp[i][m+1] = '*';
        }
        scanf("%d%d", &fromx, &fromy);
        scanf("%d%d", &tox, &toy);
    }
    
    struct node
    {
        int x, y;
        int state;
    };
    
    int myMin(int x, int y)
    {
        if (x == -1) return y;
        if (y == -1) return x;
        return min(x, y);
    }
    
    void work()
    {
        node t, k;
        queue<node> q;
        t.x = fromx; t.y = fromy; t.state = 0;
        s[t.x][t.y][t.state] = 0;
        q.push(t);
        while (!q.empty())
        {
            t = q.front();
            q.pop();
    
            k = t;
            k.state = (k.state+1)%4;
            if (s[k.x][k.y][k.state] == -1)
            {
                s[k.x][k.y][k.state] = s[t.x][t.y][t.state]+1;
                q.push(k);
            }
    
            int dir1, dir2;
            dir1 = get(mp[t.x][t.y]);
    
            //up
            if (judge(dir1, ((3+t.state)%4+4)%4))
            {
                dir2 = get(mp[t.x-1][t.y]);
                if (judge(dir2, ((1+t.state)%4+4)%4))
                {
                    k.x = t.x-1;
                    k.y = t.y;
                    k.state = t.state;
                    if (s[k.x][k.y][k.state] == -1)
                    {
                        s[k.x][k.y][k.state] = s[t.x][t.y][t.state]+1;
                        q.push(k);
                    }
                }
            }
    
            //right
            if (judge(dir1, ((2+t.state)%4+4)%4))
            {
                dir2 = get(mp[t.x][t.y+1]);
                if (judge(dir2, ((0+t.state)%4+4)%4))
                {
                    k.x = t.x;
                    k.y = t.y+1;
                    k.state = t.state;
                    if (s[k.x][k.y][k.state] == -1)
                    {
                        s[k.x][k.y][k.state] = s[t.x][t.y][t.state]+1;
                        q.push(k);
                    }
                }
            }
    
            //down
            if (judge(dir1, ((1+t.state)%4+4)%4))
            {
                dir2 = get(mp[t.x+1][t.y]);
                if (judge(dir2, ((3+t.state)%4+4)%4))
                {
                    k.x = t.x+1;
                    k.y = t.y;
                    k.state = t.state;
                    if (s[k.x][k.y][k.state] == -1)
                    {
                        s[k.x][k.y][k.state] = s[t.x][t.y][t.state]+1;
                        q.push(k);
                    }
                }
            }
    
            //left
            if (judge(dir1, ((0+t.state)%4+4)%4))
            {
                dir2 = get(mp[t.x][t.y-1]);
                if (judge(dir2, ((2+t.state)%4+4)%4))
                {
                    k.x = t.x;
                    k.y = t.y-1;
                    k.state = t.state;
                    if (s[k.x][k.y][k.state] == -1)
                    {
                        s[k.x][k.y][k.state] = s[t.x][t.y][t.state]+1;
                        q.push(k);
                    }
                }
            }
        }
        int ans = -1;
        ans = myMin(ans, s[tox][toy][0]);
        ans = myMin(ans, s[tox][toy][1]);
        ans = myMin(ans, s[tox][toy][2]);
        ans = myMin(ans, s[tox][toy][3]);
        printf("%d
    ", ans);
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        //freopen("test.out", "w", stdout);
        while (scanf("%d%d", &n, &m) != EOF)
        {
            input();
            work();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    js简单对象List自定义属性排序
    我所理解的Vue——学习心得体会1(Vue对象)
    vue的checkbox或多选的select的代码例子
    display:inline; display:block;
    托管到github上的网页图片在百度浏览器中显示不全
    background-position
    鼠标焦点变化引起mouseout事件
    jquery检查元素存在性
    nodevalue
    链接被点击的默认行为——带到另一个窗口
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/5530778.html
Copyright © 2020-2023  润新知