【codevs4696】等差数列

题目大意:给定 N 个整数组成的集合,向集合中添加一个整数,使得这 N+1 个整数组成等差数列,求这样的整数有多少个。

题解:
引理1:若原集合中只有一个元素,则有无数种可能。
引理2:若原集合中有且仅有两个整数,则最多可能有 3 种答案。
引理3:若原集合已经能够组成等差数列,则只能在序列首尾添加元素。
引理4:若原集合中的数字不能构成等差数列,且其差分序列有超过两个不相等的值,则无解。
引理5:若原集合中的数字不能构成等差数列,且其差分序列有且仅有两个相等的值,且相对较大的值有且仅有一个,且这个值是较小值的二倍时,才有且仅有一个答案。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=60;

int n,ans,tot,a[maxn],delta[maxn];
map<int,int> mp;

void read_and_parse(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	sort(a+1,a+n+1);
	for(int i=2;i<=n;i++)delta[i]=a[i]-a[i-1];
}

bool check(){
	int d=a[2]-a[1];
	for(int i=3;i<=n;i++)if(a[i]-a[i-1]!=d)return 0;
	return 1;
}

void solve(){
	if(n==1){puts("-1");return;}
	else if(n==2){
		if(a[1]==a[2]){
			puts("1");
			printf("%d\n",a[1]);
		}
		else if((a[1]+a[2])%2==0){
			puts("3");
			printf("%d %d %d\n",2*a[1]-a[2],(a[1]+a[2])/2,2*a[2]-a[1]);
		}else{
			puts("2");
			printf("%d %d\n",2*a[1]-a[2],2*a[2]-a[1]);
		}
		return;
	}
	else if(check()){
		int d=a[2]-a[1];
		if(!d){puts("1");printf("%d\n",a[1]);}
		else{puts("2");printf("%d %d\n",a[1]-d,a[n]+d);}
	}else{
		for(int i=2;i<=n;i++)mp[delta[i]]++;
		if(mp.size()>2){puts("0");return;}
		map<int,int>::iterator p=mp.begin(),q=--mp.end();
		if(q->second>1){puts("0");return;}
		if(q->first!=p->first*2){puts("0");return;}
		puts("1");
		int goal=q->first;
		for(int i=2;i<=n;i++)if(delta[i]==goal){
			printf("%d\n",a[i]-goal/2);
			break;
		}
	}
}

int main(){
	read_and_parse();
	solve();
	return 0;
}
posted @ 2018-11-28 22:06  shellpicker  阅读(194)  评论(0编辑  收藏  举报