416D Population Size


题目 :    http://codeforces.com/problemset/problem/416/D


思路:从上一个等差数列的结尾加一处开始找两个非-1的数,算出公差。如果公差为小数或者该公差导致前面的一串-1中有可能会有数变成非正数,就将第一个非-1的数和前面的一堆-1和两数间的一堆-1作为第一个数列,再以第二个非-1的数开头找等差数列。否则就再向后找可以合并到这个等差数列的数加入这个数列,找不到了就从这个等差数列的结尾加一处再找等差数列。


最开始我想不出来,然后看了提示,按照提示写了。过了样例后提交了17次,然后再79个点死活过不去了。

主要是犯了这些错误:

    1、开头、结尾是-1时处理不当

    2、公差为小数时没有考虑

    3、应该用long long 型存储

                  ……





然后看了别人的程序,思路差不多,写的有些不同。我原来的程序是对每个数判断看能否加入前一个等差数列,而那个程序是按上面的思路写的,对于前面的-1变得小于等于0的情况处理的也好一些。我又写了一遍,然后就过了。


#include<stdio.h>
#include<iostream>
using namespace std;
long long n;
long long a[200005]= {0};
long long sum=0;
int main() {
	scanf("%I64d",&n);
	for(long long i=1; i<=n; i++) {
		scanf("%I64d",&a[i]);
	}
	long long i=1;
	while(i<=n) {
		sum++;
		long long firstnum=0,nextnum=0;
		for(long long j=i; j<=n; j++) {
			if(a[j]>=0) {
				if(firstnum==0) {
					firstnum=j;
				} else {
					nextnum=j;
					break;
				}
			}
		}
		if(nextnum==0) {
			break;
		}
		if((a[nextnum]-a[firstnum])%(nextnum-firstnum)!=0) {
			i=nextnum;
			continue;
		}
		long long d=(a[nextnum]-a[firstnum])/(nextnum-firstnum);
		if(a[nextnum]-(nextnum-i)*d<=0) {
			i=nextnum;
			continue;
		}
		long long x=a[nextnum];
		for(i=nextnum+1; i<=n; i++) {
			if(x+d<=0) {
				break;
			}
			if(a[i]==-1||a[i]==x+d) {
				x+=d;
			} else {
				break;
			}
		}
	}
	printf("%I64d",sum);
	return 0;
}


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值