【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;
}

猜你喜欢

转载自www.cnblogs.com/wzj-xhjbk/p/10035305.html