• Codeforces 831 A Unimodal Array 模拟(我感觉我现在比任何时候都理解程序员就是专门写各种Bug这句话)


      题目链接: http://codeforces.com/problemset/problem/831/A

      题目描述: 让你判断数列是不是符合题目描述的规律增长

      解题思路: 我知道我的思路是对的, 但是肯定是不好的, 因为BUG·特别难找

      代码: 

    #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
    #define mem0(a) memset(a,0,sizeof(a))
    #define meminf(a) memset(a,-0x3f,sizeof(a))
    #define fi(n) for(i=0;i<n;i++)
    #define fj(m) for(j=0;j<m;j++)
    #define sca(x) scanf("%d",&x)
    #define scalld(x) scanf("%I64d",&x)
    #define print(x) printf("%d
    ", x)
    #define printlld(x) printf("%I64d
    ",x)
    #define de printf("=======
    ")
    #define yes printf("YES
    ")
    #define no printf("NO
    ")
    typedef long long ll;
    using namespace std;
    
    const int maxn = 1e3+10;
    int a[maxn];
    
    int main() {
        int n;
        sca(n);
        for( int i = 1; i <= n; i++ ) {
            sca(a[i]);
        }
    //    for( int i = 2; i <= n; i++ ) {
    //        cout << a[i]-a[i-1] << endl;
    //    }
        if( n == 1 ) {
            yes;
            return 0;
        }
        int flag = 1;
        for( int i = 2; i <= n; i++ ) {
            if( a[i] <= a[i-1] ) {
                flag = 0;
                break;
            }
        }
        //    cout << flag << endl;
        if( flag ) {
            yes;
            return 0;
        }
        flag = 1;
        for( int i = 2; i <= n; i++ ) {
            if( a[i] >= a[i-1] ) {
                flag = 0;
                break;
            }
        }
        if( flag ) {
            yes;
            return 0;
        }
        if( a[1] > a[2] || a[n] > a[n-1] ) {
            no;
            return 0;
        }
        flag = 1;
        for( int i = 2; i <= n; i++ ) {
            if( a[i] != a[1] ) flag = 0;
        }
        if( flag ) {        // 平着
            yes;
            return 0;
        }
        
        flag = 1;
        int cnt = 0;
    //    cout << cnt << endl;
        for( int i = 2; i <= n; i++ ) {
            if( a[i] == a[i-1] && flag ) {
    //            cout << i << " " << flag << endl;
                cnt++;
                flag = 0;
            }
            else if( a[i] != a[i-1] ) flag = 1;
        }
    //    cout << cnt << endl;
        if( cnt > 1 ) { // 保证了至多有一段儿是平着的
            no;
            return 0;
        }
        flag = 1;
        if( a[1] == a[2] ) {
            int i;
            for( i = 2; i <= n; i++ ) {
                if( a[i] != a[i+1] ) break;
            }
            for( int j = i; j <= n-1; j++ ) {
                if( a[j+1] >= a[j] ) {
                    flag = 0;
                    break;
                }
            }
            if( flag == 1 ) {  // 先平再down
                yes;
                return 0;
            }
        }
        flag = 1;
    //    cout << a[n] << " " << a[n-1] << endl;
        if( a[n] == a[n-1] ) {
    //        de;
            int i;
            for( i = n; i >= 2; i-- ) {
                if( a[i] != a[i-1] ) break;
            }
    //        cout << i << endl;
            for( int j = 2; j <= i; j++ ) {
    //            if( a[j] == 921 ) {
    //                cout << a[j+1] << endl;
    //            }
                if( a[j] <= a[j-1] ) {
                    flag = 0;
                    break;
                }
            }
            if( flag ) { // 先上升再平着
    //            de;
                yes;
                return 0;
            }
        }
        int start = -1;
        for( int i = 2; i <= n; i++ ) {
            if( a[i] == a[i-1] ) {
                start = i-1;
                break;
            }
        }
    
        int end = -1;
        for( int i = n; i >= 2; i-- ) {
            if( a[i] == a[i-1] ) {
                end = i;
                break;
            }
        }
    //    cout << start << end << endl;
        if( start == -1 ) {
            for( int i = 2; i <= n; i++ ) {
                if( a[i] < a[i-1] ) {
                    start = end = i-1;
                    break;
                }
            }
        }
    //    cout << start << end << endl;
        flag = 1;
        for( int i = 2; i <= start; i++ ) {
            if( a[i] <= a[i-1] ) {
                flag = 0;
                break;
            }
        }
        for( int i = n; i > end; i-- ) {
            if( a[i] >= a[i-1] ) {
                flag = 0;
                break;
            }
        }
        if( flag ) {
            yes;
            return 0;
        }
        no;
        return 0;
    }
    View Code

      思考: 如题目所说, 哎.......我一开始看到这道题的时候觉得应该枚举一些不可以的特殊情况, 但是不可以的情况实在太多了.....所以我就想干脆直接把所有合法情况都判断出来, 剩下的都是不行的, 就是这个傻逼思路让我苦苦调BUG调了小两个小时.......我的代码能力很渣, 所以应该想一些巧的思路的, 但是我一直觉得自己暴力的话是能够写出来的........然后就是各种烦, 自己也越来越不想换一个思路, 宁愿死磕到......哎, 以后要长记性啊, 明确思路, 这次CF只做出来一道题.......说好的看D呢......这两天有的忙了.....组合数学, 数论, 今天的CF, 昨天的Hihocoder, 今天晚上的CF教育场, 再加上自己要做线段树和DP的专题.......好多好多题要补啊.....先不打比赛了.......哎

      代码: 

    #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
    #define mem0(a) memset(a,0,sizeof(a))
    #define meminf(a) memset(a,-0x3f,sizeof(a))
    #define fi(n) for(i=0;i<n;i++)
    #define fj(m) for(j=0;j<m;j++)
    #define sca(x) scanf("%d",&x)
    #define scalld(x) scanf("%I64d",&x)
    #define print(x) printf("%d
    ", x)
    #define printlld(x) printf("%I64d
    ",x)
    #define de printf("=======
    ")
    #define yes printf("YES
    ")
    #define no printf("NO
    ")
    typedef long long ll;
    using namespace std;
    
    int a[111];
    
    int main() {
        int n;
        sca(n);
        for( int i = 1; i <= n; i++ ) {
            sca(a[i]);
        }
        int inc = 0, dec = 0, hod = 0, flag = 1;
        for( int i = 1; i < n; i++ ) {
            if( a[i] < a[i+1] ) {
                if( hod || dec ) {
                    flag = 0;
                    break;
                }
                else if( !inc ) {
                    inc = 1;
                }
            }
            else if( a[i] == a[i+1] )  {
                if( dec ) {
                    flag = 0;
                    break;
                }
                hod = 1;
            }
            else if( a[i] > a[i+1] ) {
                dec = 1;
            }
        }
        if( flag ) {
            printf( "YES
    " );
        }
        else {
            printf( "NO
    " );
        }
        return 0;
    }
    View Code

      思考*2: 这他妈才是正确思路啊......我们只需要从几个角度去考虑问题,平稳之后不能上升, 下降之后不能平稳, 平稳之前可以上升这几点来考虑, 代码没几行就写完了啊.....正确性保证就根据连续判断每一个区间之差, 根据正负和三个变量来确定

  • 相关阅读:
    Codeforces Round #733
    [ZJOI2007] 时态同步(树形dp)
    最大子树和(树形dp)
    P2015 二叉苹果树
    没有上司的舞会(经典树形dp)
    P3884 [JLOI2009]二叉树问题(LCA)
    Bin Packing Problem(线段树 + multiset)
    P4281 [AHOI2008]紧急集合 / 聚会(最近公共祖先)
    P3128 [USACO15DEC]Max Flow P(LCA 树上差分)
    java中Set接口用法
  • 原文地址:https://www.cnblogs.com/FriskyPuppy/p/7405135.html
Copyright © 2020-2023  润新知