标签:style blog http io os ar for strong sp
转载请注明本文链接 http://blog.csdn.net/yangnanhai93/article/details/40474355
题目链接地址:http://ac.jobdu.com/problem.php?pid=1377
这道题目的难点在于如何分析出缓变序列的特征:
1:缓变序列排序之后必须连续
证明:假设排序之后的序列为a[1] a[2] a[3]... a[n],其中a[n]-a[n-1]>1,即an与前面的数不连续,因为缓变序列要求任何一个数的前后的变化都是1,然而对于a[n],没有任何一个数可以在其前后使得满足缓变序列的性质,所以排序之后数组必须是连续的
2:缓变序列应当满足的要求是构成一个新的数组记为数组A,该数组具有如下性质:
A[1]=a1,A[n]=an-A[n-1].对于1-n的A[n],需要满足A[n]=0,且1-(n-1)时: A[n]>0 (A数组表示的意思就是还剩下多少个位置需要填补)
证明:对于1-(n-1),记为m时,如果A[m]<=0,此时,能够得到如若A[m]=0,恰好得到一个缓变序列,如果A[m]<0,则说明m的个数少于m-1位需要的,则肯定不能满足要求
对于n位,正如上面说明A[n]=0,使得缓变序列的需要填补的数恰好满足。
下面用图的方式来帮助理解,通过画线,很明显知道必须是上一层的点必须大于下一层的点的数目(最后一层除外),也必须满足A[n]=0
#include <iostream> #include <memory.h> using namespace std; int main() { //freopen("data.in","r",stdin); int num,A[10001],tmp,low,high; while(cin>>num) { memset(A,0,sizeof(A)); for(int i=0;i<num;i++) { cin>>tmp; A[tmp]++; } low=0; while(A[low]==0) low++; tmp=0; high=low; while(A[high]!=0) { tmp+=A[high]; high++; } if(num==tmp) { bool isTrue=true; tmp=0; for(int i=low;i<high-1;i++) { tmp=A[i]-tmp; if(tmp<=0) { isTrue=false; break; } } if(A[high-1]-tmp) isTrue=false; if(isTrue) cout<<"YES"<<endl; else cout<<"NO"<<endl; } else cout<<"NO"<<endl; } return 0; } /************************************************************** Problem: 1377 User: vincent_ynh Language: C++ Result: Accepted Time:40 ms Memory:1520 kb ****************************************************************/
标签:style blog http io os ar for strong sp
原文地址:http://blog.csdn.net/yangnanhai93/article/details/40474355