hdu 4928 Series 2
给定原始序列A Bi=Ai+1-Ai 得到序列B 然后判断序列的单调性
按照此方法往下继续构造序列 如果序列都是单调的 则是 nice series 如果序列一开始就不是单调的 就是nice series
如果一开始是单调的 但不是nice 则输出知道第i个序列是单调的
看的的别人的思路 挺好的 讲的也很清楚 http://blog.csdn.net/u011332631/article/details/38440659
这个题主要在于需要将前后的0合并起来,因为0-0=0,所以没有必要做多余的计算
而题解给出的证明也是非常精妙
设原序列的最大值减最小值为V
设i递增序列的Max-Min==U
则可以得到如下性质:
1、第i+1个序列的最大值不会超过U
2、第i+1个序列的总和为U
因为a[i+1][1]+a[i+1][2]+....+a[i+1][n]=a[i][2]-a[i][1]+a[i][3]-a[i][2]+.....a[i][n+1]-a[i][n]
=a[i][n+1]-a[i][1]=U、
3、第i+1个序列全部大于等于0(因为序列i递增)
4、第i+1个序列的序列最多有一个数大于U/2
因此可以得到,最多会进行logV次序列操作(因为当Max-Min==0时就可以退出了)
而每次操作的复杂度为O(n),因此总的复杂度为O(n*logV)
其他的就是简单的模拟了
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#define eps 1e-8
#define op operator
#define MOD 10009
#define MAXN 100010
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FOV(i,a,b) for(int i=a;i>=b;i--)
#define REP(i,a,b) for(int i=a;i<b;i++)
#define REV(i,a,b) for(int i=a-1;i>=b;i--)
#define MEM(a,x) memset(a,x,sizeof a)
#define ll __int64
using namespace std;
ll a[MAXN];
ll b[MAXN];
int n;
int check(int num)
{
int flag=1;
for(int i=0;i<num-1;i++)
if(a[i]>a[i+1]) flag=0;//判断是否递减
if(flag) return 1;//递减返回1
flag =1;
for(int i=0;i<num-1;i++)
if(a[i]<a[i+1]) flag=0;//判断是否递增
if(flag) return -1;//递增返回-1
else return 0;//不单调
}
void solve()
{
int cnt=n;
int head=0,tail=0;
for(int i=0;i<n;i++)
{
if(i==n-1||cnt==1)
{
printf("nice series\n");
return;
}
int flag=check(cnt);
if(flag==0)
{
if(i==0) printf("ugly series\n");
else printf("%d\n",i-1);
return;
}
else if(flag==-1)
{
for(int j=0;j<cnt/2;j++)
swap(a[j],a[cnt-1-j]);
swap(head,tail);
}
int num=0;
if(head) { b[num++]=0; head--; }
for(int j=0;j<cnt-1;j++)
b[num++]=a[j+1]-a[j];
if(tail) { b[num++]=0; tail--; }
int x=1;
cnt=0;
a[cnt++]=b[0];
if(a[0]==0)
while(b[x]==0&&x<num)
{
head++; x++;
}
for(;x<num;x++) a[cnt++]=b[x];
if(a[cnt-1]==0)
while(a[cnt-2]==0&&cnt-2>=0)
{
cnt--; tail++;
}
}
}
int main()
{
freopen("ceshi.txt","r",stdin);
int tc;
scanf("%d",&tc);
while(tc--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%I64d",&a[i]);
solve();
}
return 0;
}