来源:JZOJ
题目描述
坚持每天刷题,这是每个信奥选手的基本技能,岳老师也一直在默默的记录信奥班的刷题情况。
她的记录方式是设计了一个记录方案,如果某天全班都没有刷题,就会在当天记录下 0 0 0,如果某天全班都没有刷题发生在 2 2 2 天前,就会在当天记录下 2 2 2.
岳老师每天都会做下当天的记录。
比如:第 1 1 1 天和第 4 4 4 天没刷题,那么前8天的记录序列为: 01201234 0 1 2 0 1 2 3 4 01201234;
N N N 天过去了,岳老师要做下统计,但是因为 U U U盘出现了一些状况,一些记录竟然找不到了。只留下了一部分。
岳老师知道一共记录了 N N N 天,现在她要让你帮她计算出,根据现有的情况下,信奥班最多和最少的没有刷题的天数。
岳老师还确信,她肯定是从某天没写作业开始的记录的。
输入格式
第一行一个整数 N N N;
第二行 N N N 个整数,第 i i i 个数 a i a_i ai 如果为 − 1 -1 −1,表示第 i i i 条记录丢失,如果不是 − 1 -1 −1,表示第 i i i 条记录的值。
输出格式
如果没有任何可能的序列与提供的序列一致,输出 − 1 -1 −1; 否则输出两个整数 m i n m minm minm 和 m a x m maxm maxm。表示可能的最少天数与最多天数。
解题思路
- 这道题的核心就是判断此序列是否合法,也就是说有没有可能的序列与提供的序列一致。
- 其实这个细节还是很好处理的,当我们找到一个 a [ i ] a[i] a[i] 不是 − 1 -1 −1 的,根据题意,那就说明第 i − a [ i ] i-a[i] i−a[i] 天全班没有刷题,那么就可以得出 a [ i − 1 ] a[i-1] a[i−1] 等于 a [ i ] − 1 a[i]-1 a[i]−1, a [ i − 2 ] a[i-2] a[i−2] 等于 a [ i ] − 2 a[i]-2 a[i]−2 ……以此类推。但如果 a [ k ] > 0 a[k]>0 a[k]>0 而且 a [ k ] ! = j a[k]!=j a[k]!=j 呢?( k k k 枚举 i i i 之前的每一个位置, j j j 枚举前 i − 1 i-1 i−1 个位置由 a [ i ] a[i] a[i] 推导出的数字)这样的话第 k k k 个位置不就有两个数字,矛盾了吗?输出 − 1 -1 −1,果断 r e t u r n return return 0 ; 0; 0;
- 这样就算 A A A 掉了,说实话挺水的 Q A Q QAQ QAQ
Code
#include <bits/stdc++.h>
using namespace std;
int a[210];
int main()
{
freopen("homework.in","r",stdin);
freopen("homework.out","w",stdout);
int n;
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if (a[i]>0)
{
int k=i-1;
for (int j=a[i]-1;j>=0;j--) //往前推导
{
if (a[k]>0 && a[k]!=j) //不合法
{
printf("-1");
return 0;
}
a[k]=j; //赋值
k--;
}
}
}
a[1]=0;
int mins=0,s=0;
for (int i=1;i<=n;i++)
{
if (a[i]==0) mins++; //如果是0那么这天肯定没刷题
if (a[i]==-1) s++; //如果是-1那么这天可以是刷题或不刷题
}
printf("%d %d",mins,mins+s);
return 0;
}