CodeForces 451B


#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int n;
struct Node
{
    int x,id;
}p[100010];

bool cmp(Node x,Node y)
{
    return x.x<y.x;
}

int main()
{
    int l = -1,r;
    bool flag = true;
    cin >> n;
    for(int i=1;i<=n;i++)
    {
        cin >> p[i].x;
        p[i].id=i;
    }
    sort(p+1,p+n+1,cmp);
    p[n+1].id = -1;
    for(int i =1; i<=n;i++)
    {
        if(p[i].id!= i)
        {
            l=i;
            break;
        }
    }
    if(l == -1){
      cout<< "yes" <<endl<< "1  1"<< endl;
      return 0;
    }
    for(int i =l;i <= n;i++)
    {
        if(p[i].id- p[i+1].id!= 1)
        {
            r=i;
            break;
        }
    }

    for(int i=r+1;i<= n;i++)
    {
        if(p[i].id != i)
        {
            flag=false;
            break;
        }
    }

    if(flag){
        cout<< "yes" << endl<< l<<"  "<<r<<endl;
    }
    else cout<<"no" << endl;
    return 0;

}
View Code

 

陶叔的讲解,我的代码!
题意:给你一个长度不超过10^5的数组,数组中的每个元素互不相同。
•问是否能翻转数组的某个区间,使得数组形成一个有序的升序序列。
•先按数组元素值的大小排序
•排完序之后,就能形成一个序列id[i]
•id[i]表示第i个数字在数组中的大小排名第几
•比如说:
•a[1]=1,a[2]=10,a[3]=6,a[4]=2,a[5]=11
•id[1]=1,id[2]=4,id[3]=3,id[4]=2,id[5]=5
•a[1]=1,a[2]=10,a[3]=6,a[4]=2,a[5]=11
•id[1]=1,id[2]=4,id[3]=3,id[4]=2,id[5]=5
•于是我们发现,如果我们能将id区间的某一段翻转过后,使得id[i]=i,那么就可以找到满足题意的区间
•找左端点L:第一个id[i]不等于i的端点
•找右端点R:第一个id[i]-id[i+1]不等于1的端点
•接下来我们需要验证剩余的i>R,id[i]是否等于i
posted @ 2014-07-27 17:27  TK在颤抖  阅读(170)  评论(1编辑  收藏  举报