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\n", x)
#define printlld(x) printf("%I64d\n",x)
#define de printf("=======\n")
#define yes printf("YES\n")
#define no printf("NO\n")
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\n", x)
#define printlld(x) printf("%I64d\n",x)
#define de printf("=======\n")
#define yes printf("YES\n")
#define no printf("NO\n")
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\n" );
    }
    else {
        printf( "NO\n" );
    }
    return 0;
}
View Code

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

posted on 2017-08-21 16:30  FriskyPuppy  阅读(122)  评论(0编辑  收藏  举报

导航