• Educational Codeforces Round 25 思维


      比赛链接: https://vjudge.net/contest/178158#overview

      A: Binary Protocal

      题目描述: 规定一个数转化成“二进制”, 各个数位上的数字为1的个数, 两个数位之间相隔一个0, 如果数位本身为0, 相当于输出0个1再输出一个0, 现在知道了“二进制”, 让你反推这个数

      解题思路: 一开始我又犯蠢了, 这么一道简单题浪费了很多时间, 快半个点儿吧, 实际上是只需要结束的时候特判一下最后一位是否为0 就可以

      代码:

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <map>
    #include <cstring>
    #include <iterator>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <deque>
    
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    using namespace std;
    
    int main() {
        int n;
        string s;
        cin >> n >> s;
        int ans = 0;
        for( int i = 0; i < n; i++ ) {
            if( s[i] == '1' )
                ans++;
            if( s[i] == '0'|| i == n-1 ) {
                cout << ans;
                ans = 0;
            }
        }
        if( s[n-1] == '0' )
            cout << "0";
        cout << endl;
        return 0;
    }
    View Code

      思考:一道水题自己也写了好长时间......想不到点子上面......

      B: Five in a row

      题目描述: 给你一个棋盘, 让你判断能不能再放一个黑子使之成为五连, 棋盘很小

      解题思路: 暴力就可以, 将黑子转换为1, 空闲转换为0, 在八个方向中都加一遍(其实仅仅需要四个方向), 如果 == 4就输出 yes

      代码: 

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstring>
    #include <iterator>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <deque>
    
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    using namespace std;
    char graph[20][20];
    int turn[20][20];
    
    int main() {
        memset( graph, 0, sizeof(graph) );
        memset( turn, 0, sizeof(turn) );
        for( int i = 1; i <= 10; i++ ) {
            for( int j = 1; j <= 10; j++ ) {
                cin >> graph[i][j];
                if( graph[i][j] == 'X' )
                    turn[i][j] = 1;
                else if( graph[i][j] == 'O' )
                    turn[i][j] = -1;
                else if( graph[i][j] == '.' )
                    turn[i][j] = 0;
            }
        }
    //    for( int i = 1; i <= 10; i++ ) {
    //        for( int j = 1; j <= 10; j++ ) {
    ////            cout << graph[i][j] << " ";
    //            cout << turn[i][j] << " ";
    //        }
    //        cout << endl;
    //    }
        int ans = 0;
        for( int i = 1; i <= 10; i++ ) {
            for( int j = 1; j <= 10; j++ ) {
                if( turn[i][j] == 1 || turn[i][j] == 0 ){
                    int a, b, c, d, e, f, g, h;
                    a = b = c = d = e = f = g = h = 0;
                    for( int k = 0; k < 5; k++ ) {
                        if( j <= 6 ) a += turn[i][j+k]; // right
                        if( i <= 6 ) b += turn[i+k][j]; // down
                        if( j <= 6 && i <= 6 ) c += turn[i+k][j+k]; // eastsouth
                        if( i >= 5 && j >= 5 ) d += turn[i-k][j-k]; // westnorth
                        if( i >= 5 && j <= 6 ) e += turn[i-k][j+k]; // eastnorth
                        if( i <= 6 && j >= 5 ) f += turn[i+k][j-k]; // westsouth
                    }
                    ans = max(a,max(b,max(c,max(d,max(e,f)))));
                    //cout<<ans<<endl;
                    if( ans == 4 ) {
                        cout << "YES" << endl;
                        return 0;
                    }
                }
            }
        }
        cout<<"NO"<<endl;
        return 0;
    }
    View Code

      思考: 以前做过好多遍了......

      C: Multi judge solving

      题目描述: 这个题看了好久.....就是给你一组数, 和一个K, 只要小于等于2 * k都可以立刻被忽略掉并且k被取代成k与这个数之间更大的数,但是k * 2需要代价, 问最小代价是多少

      解题思路: 排序, 设置cnt记录k * 2的次数, 每次更新k为k 与 a[i]的最大值

      代码:

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstring>
    #include <iterator>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <deque>
    
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    using namespace std;
    
    int a[1000+50];
    
    int main() {
        int n, k;
        cin >> n >> k;
        for( int i = 1; i <= n; i++ ) {
            cin >> a[i];
    //        if( a[i] <= k*2 ) a[i] = 0;
        }
        sort( a+1, a+n+1 );
    //    for( int i = 1; i <= n; i++ ) {
    //        cout << a[i] << " ";
    //    }
    //    cout << endl;
        int ans = 0;
        for( int i = 1; i <= n; i++ ) {
            while( a[i] > k*2 ) {
                k *= 2;
                ans++;
            }
            k = max( k, a[i] );
        }
        cout << ans << endl;
    }
    View Code

      思考: 自己一开始读错题了.....并没有更新K, WA了一发, 好好读题....

      D: Suitable replacement  

      题目描述: 给你连个字符串, 第一个字符串内可能有问号, 现在让你用任意的字母替换问号, 使得第一个字符串能够出现最多次数的字符串二, 不重叠(还有串s可以随意排序)

      解题思路: 首先特判问号个数为0或者len2 > len1的情况,抠掉。 然后直接看字符串t中各个字母,如果各个字母出现在s中就可以抵消掉一部分, 否则只能用问号抵消。 所以我们直接遍历字符串t各个字母, 如果出现在字符串s , 不去管它, 当然s中的该字符的次数要--, 否则出现一个没有出现过的字符就直接用它替换问号。

      代码: 

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstring>
    #include <iterator>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <deque>
    #include <map>
    #define lson l, m, rt<<1
    #define rson m+1, r, rt<<1|1
    using namespace std;
    
    map<char, int> ms;
    map<char, int> mt;
    stack<char> ans;
    
    int main() {
        ms.clear();
        mt.clear();
        string s;
        string t;
        cin >> s >> t;
        int len1 = (int)s.length();
        int len2 = (int)t.length();
        int cnt = 0;
        for( int i = 0; i < len1; i++ ) {
            if( s[i] == '?' ) cnt++;
            ms[s[i]]++;
        }
        for( int i = 0; i < len2; i++ ) {
            mt[t[i]]++;
        }
        if( cnt == 0 || len2 > len1 ) {
            cout << s << endl;
            return 0;
        }
        while( cnt ) {
            for( int i = 0; i< len2; i++ ) {
                if( ms[t[i]] ) ms[t[i]]--;
                else {
                    ans.push(t[i]);
                    cnt--;
                    if( cnt == 0 ) break;
                }
            }
        }
        for( int i = 0; i < len1; i++ ) {
            if( s[i] == '?' ) {
                char res = ans.top();
                ans.pop();
                s[i] = res;
            }
        }
        cout << s << endl;
        return 0;
    }
    View Code

      思考: 这种思维题有的没有那么复杂, 很大一部分靠贪心就能解出来

      比赛总结: 以后多做点儿这种题吧, 挺有意思的, 再说自己的手速码力和思维都有待提高.......

  • 相关阅读:
    如何重写Java中的equals方法
    如何阅读论文
    新的开始
    react父组件调用子组件方法
    关于 webpack 的研究
    浅析HTTP代理原理
    Maven POM详解
    项目实战
    项目实战-Gulp使用
    AngularJS 项目开发实战
  • 原文地址:https://www.cnblogs.com/FriskyPuppy/p/7346865.html
Copyright © 2020-2023  润新知