Taming the Herd
题意
给你n个数,每个数不是-1就是一个非负数。-1表示当天这个记录器上的数消失,而非负数表示当天记录器上显示的数字(数字表示当天早上离最近一次羊破坏围栏的天数)例如0表示当天早上羊破坏围栏。注意根据题意第一天早上的数字必须是0或者是-1.问你羊破坏围栏次数的最小值与最大值。
分析
(1)数据的合理性 1
例如 1 2 3 3就是属于不合理的数。
合理性的数据包括两个特征
a、从最右边开始向左边看,

  1. 当右边不是0或-1且左边不是-1的时候,右边总是比左边多一个数。如果左边数不是右边数-1那么这个数据就不合理。
  2. 当右边是0或-1的时候,直接跳过这个数
  3. 当右边不是0或-1但是左边是-1的时候,把右边数-1赋值给左边的数
  4. 经过1、2、3步骤的处理,这个数据会发生一系列的变化。
    (2)数据合理性 2
    对于第一个数据合理性并没有解决第一天早上的数字必须是0或-1.
    通过数据合理性1的处理,第一天的数据只能是0或者是-1的。
    可以特判第一个数,如果是0或-1则数据合理,否则就不合理。
    如果合理,就把第一个数据改成0

(3)数据合理性解决了,那我们就来看看这个问题怎么解了。
经过这个合理数据的处理后
对于仍有-1的个数就是最大值与最小值的差。
最小值得个数其实就是修改后数据0的个数
最大值就是最小值±1的个数

AC代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int a[105];
int main(){
int i,n,mi=0,ma=0;
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
for(i=n;i>=2;i--){
	if(a[i]!=-1&&a[i]!=0) {
	if(a[i-1]==-1) {a[i-1]=a[i]-1;}
	else {
		if(a[i-1]!=a[i]-1)
			{cout<<-1<<endl;return 0;}

	}
}
}
if(a[1]==-1) a[1]=0;
if(a[1]!=0){
	cout<<-1<<endl;return 0;
}//数据合理性的处理
for(i=1;i<=n;i++){
	if(a[i]==0) {mi++;ma++;}
	else{
		if(a[i]==-1) ma++;
	}
}
cout<<mi<<' '<<ma<<endl;
return 0;
}