文章标题 Coderforces 382C :Arithmetic Progression(代码能力+细心分类)

Arithmetic Progression

Description
Everybody knows what an arithmetic progression is. Let us remind you just in case that an arithmetic progression is such sequence of numbers a1, a2, …, an of length n, that the following condition fulfills:
a2 - a1 = a3 - a2 = a4 - a3 = … = ai + 1 - ai = … = an - an - 1.
For example, sequences [1, 5], [10], [5, 4, 3] are arithmetic progressions and sequences [1, 3, 2], [1, 2, 4] are not.
Alexander has n cards containing integers. Arthur wants to give Alexander exactly one more card with a number so that he could use the resulting n + 1 cards to make an arithmetic progression (Alexander has to use all of his cards).
Arthur has already bought a card but he hasn’t written a number on it. Help him, print all integers that you can write on a card so that the described condition fulfilled.
Input
The first line contains integer n (1 ≤ n ≤ 105) — the number of cards. The next line contains the sequence of integers — the numbers on Alexander’s cards. The numbers are positive integers, each of them doesn’t exceed 108.
Output
If Arthur can write infinitely many distinct integers on the card, print on a single line -1.
Otherwise, print on the first line the number of integers that suit you. In the second line, print the numbers in the increasing order. Note that the numbers in the answer can exceed 108 or even be negative (see test samples).
Sample Input
Input
3
4 1 7
Output
2
-2 10
Input
1
10
Output
-1
Input
4
1 3 5 9
Output
1
7
Input
4
4 3 4 5
Output
0
Input
2
2 4
Output
3
0 3 6
题意:有n个数,然后再加入一个数,使得这n+1个数成为等差数列,问总共有多少种数字,将这些数字输出来,如果有无数种方式就输出-1
分析:分类讨论,将特殊情况拿出来先解决,当n==1时,明显有无数种情况;当n==2时,有可能有一种,有可能有三种,此时可以定义一个set,把三种情况都插入到set中,把重复的给排除了;当n==3时,就有前两个的差和后两个的差相同和不同的情况。当n>3时就考虑相邻俩个数的差不同的数有多少个,如果大于等于三说明使其变为等差数列的情况为0,然后谈论为1和2的情况。
代码:

#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<math.h>
#include<map>
#include<set>
#include<queue> 
#include<algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
int n;
int a[100005];
int main ()
{
    while (scanf ("%d",&n)!=EOF){
        for (int i=0;i<n;i++){
            scanf ("%d",&a[i]);
        }
        sort (a,a+n);
        if (n==1){
//情况为1直接输出-1
            printf ("-1\n");
            continue;
        }
        set <int>ans;
        if (n==2){
            int tmp = a[1]-a[0];
//差值
            ans.insert(a[0]-tmp);
//a[0]的左边的数
            ans.insert(a[1]+tmp);
//a[1]右边的数
            if (tmp%2==0)ans.insert(tmp/2+a[0]);/
/如果能整除,中间的数也插入
        }
        else if (n==3){
            int tmp1=a[1]-a[0],tmp2=a[2]-a[1];
            if (tmp1==tmp2){
//差值相等
                ans.insert(a[0]-tmp1);
                ans.insert(a[2]+tmp2);
            }
            else {
                if (tmp1==tmp2*2){
//差值不相等但一个为另一个的2倍
                    ans.insert(a[0]+tmp2);
                }
                else if (tmp1*2==tmp2){
                    ans.insert(a[2]-tmp1);
                }
            }
        }
        else {
//大于3的情况
            int cnt=0;
            int tmp[15];
            map<int,int> mp;
//用一个map,来求差值的个数
            for (int i=1;i<n;i++){
                int t=a[i]-a[i-1];
                mp[t]++;
                if (mp[t]==1){
                    tmp[cnt++]=t;
                    if (cnt>=3)break;
//如果差值超过3个说明没有
                }
            }
            if (cnt==1){
//只有一个说明可以在头尾插入一个
                ans.insert(a[0]-tmp[0]);
                ans.insert(a[n-1]+tmp[0]);
            }
            else if (cnt==2&&mp[tmp[0]]==1&&tmp[0]==tmp[1]*2){
//另外的情况有两个数,其中一个差值只有一个,并且是另外的差值的2倍
                for(int i=1;i<n;i++){
                    if (a[i]-a[i-1]==tmp[0]){
                        ans.insert(a[i-1]+tmp[1]);
                    }
                }
            }
            else if (cnt==2&&mp[tmp[1]]==1&&tmp[1]==tmp[0]*2){
                for(int i=1;i<n;i++){
                    if (a[i]-a[i-1]==tmp[1]){
                        ans.insert(a[i-1]+tmp[0]);
                    }
                }   
            }
        }
        int flag=0;
        printf ("%d\n",ans.size());
        for (set<int>::iterator i=ans.begin();i!=ans.end();i++){
//遍历set
            if (flag)printf (" ");
            printf ("%d",*i);
            flag=1;
        }
        if (ans.size())printf ("\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值