CF# IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) C - Bear and Up-Down

诶呀,其实这是一道水题,水题,水题!
真的哩,大家想想暴力怎么做=。=,然后大家就应该都会了!
题意: 一个nice的数列 对于奇数位 必须满足ai 小于ai+1,偶数位必须满足: .ai> a i + 1, 开始给定的数列一定是不nice的,然后我们可以进行一次交换(只能进行一次),把这个数列变成nice数列。

其实可以知道每一次交换毕竟只能影响那么几个数,所以如果给定的数列中不nice的数字过多,是不是可以直接判定为0? 我手写了几个,发现(没有根据)大概超过7个就很难变了,(就算超过能变,在我们程序中也不会有影响!一看程序便知), 既然这些不nice的数不多,那么我们就可以把它们提取出来,放到一个数组里面,然后把它们依次和数组中的每一个数字进行swap,检查是否这个数列nice?(检查的时候当然也是检查这个数列中的数字,和进行交换的那一位)
PS: 代码没有修改,所以可能写得有点丑啊,我尽量标注吧,原谅我这么弱.

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define mem(a) memset(a,0,sizeof(a))
#define pfn printf("\n")
#define sf scanf
#define pf printf
#define fr(i,n) for(int i=0;i<n;i++)
#define INF 0x7fffffff //INT_MAX
#define inf 0x3f3f3f3f //
const double PI = acos(-1.0);
const double e = exp(1.0);
template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
using namespace std;
#define lson l , mid , rt << 1
#define rson mid + 1 , r , rt << 1 | 1
int a[150005];
int flag[150005];
int n;
void swap(int x,int y){
    int c=a[x];
    a[x]=a[y];
    a[y]=c;
}
int check(int i){
    if(i%2==1){
        if(i==1)
            return a[1]<a[2];
        if(i>1 && (i==n || a[i]<a[i+1]) && a[i]<a[i-1])  //注意这里的条件,如果是第n个数,没必要和i+1比
            return 1;
        else
            return 0;
    }
    else{
        if(( i==n|| a[i]>a[i+1]) && a[i]>a[i-1])  //同上 注意边界处理
            return 1;
        else
            return 0;
    }
}
int main(){
    //freopen("1.txt","r",stdin);
    while(~scanf("%d",&n)){
        int len=0;
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        a[0]=a[1]+1; //下面进行选取不nice 数字的时候,避免让1和0相比较
        a[n+1]=a[n]-1; //同理 也是边界处理
        for(int i=1;i<=n;i++){ 
            if(i%2==1 && (a[i]>=a[i+1] || a[i]>=a[i-1])){
                flag[len++]=i;
            }
            else if(i%2==0 && (a[i]<=a[i+1] || a[i]<=a[i-1]) ){
                flag[len++]=i;
            }
        }
// printf("len=%d\n",len);
        if(len>7){                              //优化
            printf("0\n");
            continue;
        }
        int ans=0;
        for(int i=0;i<len;i++)
            for(int j=1;j<=n;j++){
                if(j!=flag[i]){   //如果j和flag[i] 是同一位置,那么就不需要进行交换
                    int fff=0;
                    for(int k=0;k<i;k++){
                        if(j==flag[k]){
                            fff=1;      
                            break;         
                        }
                    }
                    if(fff==1)        // 对于被选取出来的数组,因为前一个肯定和后一个进行过交换,所以后面的不需要和前面的再进行交换,否则有可能会重复计算结果
                        continue;
                    swap(flag[i],j);
                    int temp=1;
                    temp=check(j);
                    for(int k=0;k<len;k++){
                        if(!temp)   //若有一个地方不满足,那么表示整个数组都已经不nice了
                            break;
                        temp=check(flag[k]);
                    }
                    if(temp){
                        ans++;
// printf("swap=%d %d\n",flag[i],j);
                        }
                    }
                    swap(flag[i],j);
                }

        printf("%d\n",ans);
    }
    return 0;
}

你可能感兴趣的:(CF# IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2) C - Bear and Up-Down)