【2020.2.29 模拟赛】T2 作业记录 (模拟)

来源: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] ia[i] 天全班没有刷题,那么就可以得出 a [ i − 1 ] a[i-1] a[i1] 等于 a [ i ] − 1 a[i]-1 a[i]1 a [ i − 2 ] a[i-2] a[i2] 等于 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 i1 个位置由 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;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值