题意:若已知数列是在mod m 下为等差数列,求满足题意的最大的m和符合题意的c;
分析:对于成立的mod m的等差数列,公差只能由两个数组成,就是d1 , d2 分别是没有超过m , 超过m之后取余的值
这里注意到要求的是最大值m ,所以k = 1,此时对应m为最大值。
首先讨论最特殊的两种情况 ,第一种为非降序数列 , 此时说明m可以任意大 ,(每次累加c都没有超过m) ,第二种为非递增数列,(易证明这种情况是不存在的,不存在每次递增后仍会超过m(c < m) );
对于一般数列 ,利用set集合,若满足题意容器里应该只有两个数 ,一正一负 , 注意这里应该还要讨论两负的情况进行特判
#include<bits/stdc++.h>
using namespace std;
set<int> ans;
const int N = 1e5 + 10;
int a[N];
int cnt[2];
int n;
int main()
{
int t;
cin >> t;
while (t --)
{
int maxv = -1;
cin >> n;
for (int i = 1; i <= n; i ++ )
{
scanf ("%d" , &a[i]);
maxv = max (a[i] , maxv); // m一定比数列最大值还大,否则无法取模
}
if (n == 1)
{
cout << 0 << endl;
continue;
}
for (int i = 1; i + 1 <= n; i ++ ) ans.insert (a[i + 1] - a[i]); //插入每次的差值
if (ans.size() > 2) cout << -1 << endl;
else if (ans.size() == 1) cout << 0 << endl;
else
{
int s = 0 ;
for (set<int>::iterator it = ans.begin(); it != ans.end(); it ++)
{
cnt[s ++] = *it;
}
if (abs(cnt[1]) + abs(cnt[0]) < maxv) cout << -1 << endl;
else
{
if (cnt[1] < 0 && cnt[0] < 0) cout << -1 << endl; //特判
else
{
cout << abs(cnt[1]) + abs(cnt[0]) << " " << max (cnt[1] , cnt[0]) << endl; **************(1)
}
}
}
ans.clear();
}
return 0;
}
***********(1):这里举例给出下原理
又因为c没有限制,取递增时对应的值即可