题目链接
题意
给定数组,问是否可把该数组看成
a[1]=s%m
a[i]=a[i-1]+c%m(i>1)
的数组,不可以输出-1,可以的话求出最大化的m,无最大值的话输出0
思路
稍微推一下式子,得出
//答案为0:等差递减,等差递增
//答案为-1:不等差递减,不满足最后一种情况的其他情况
//有正常答案:a[i+1]-a[i] (>0时)有单个取值diff,所有a[i+1]-a[i] (>0时)+diff的最大公约数比数组任何一个数都大
教训/收获
出问题了自己造数据!注意边界条件!逻辑理清楚!多想反例!
代码
#include<cstdio>
#include<iostream>
#include<iomanip>
#include<map>
#include<unordered_map>
#include<string>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<chrono>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
#define int long long
//#define double long double
using namespace std;
typedef long long ll;
const int maxn=200505;
const int inf=0x3f3f3f3f;
int n,m,k;
int a[maxn];
int gcd(int a,int b){
return b?gcd(b,a%b):a;
}
//答案为0:等差递减,等差递增
//答案为-1:不等差递减,不满足最后一种情况的其他情况
//有正常答案:a[i+1]-a[i](>0时)有单个取值diff,所有a[i+1]-a[i](>0时)+diff的最大公约数比数组任何一个数都大
signed main(){
IOS
#ifndef ONLINE_JUDGE
freopen("D:\\_ACM_code\\IO\\in.txt","r",stdin);
freopen("D:\\_ACM_code\\IO\\out.txt","w",stdout);
#endif
int tn;
cin>>tn;
while(tn--){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
if(n==2){
cout<<0<<endl;
continue;
}
int df_ans=0;
int diff=inf;
for(int i=2;i<=n;i++){
if(a[i]>=a[i-1]){
if(a[i]-a[i-1]==diff) continue;
else {
diff=a[i]-a[i-1];
df_ans++;
}
}
}
if(df_ans==0){
diff=a[2]-a[1];
bool bl=1;
for(int i=2;i<n;i++){
if(a[i+1]-a[i]!=diff){
bl=0;
break;
}
}
if(bl)
cout<<0<<endl;
else
cout<<-1<<endl;
}
else if(df_ans>1){
cout<<-1<<endl;
}
else if(diff==0){
bool bl=1;
for(int i=1;i<n;i++){
if(a[i]!=a[i+1]){
bl=0;
break;
}
}
if(bl)
cout<<0<<endl;
else
cout<<-1<<endl;
}
else{
bool bl=0;
int ans;
bool has=0;
for(int i=2;i<=n;i++){
if(a[i]<a[i-1]){
has=1;
if(!bl){
bl=1;
ans=a[i-1]-a[i]+diff;
}
else{
ans=gcd(ans,a[i-1]-a[i]+diff);
}
}
}
if(!has){
cout<<0<<endl;
continue;
}
bl=1;
for(int i=1;i<=n;i++){
if(a[i]>=ans){
bl=0;
break;
}
}
if(bl)
cout<<ans<<' '<<diff<<endl;
else
cout<<-1<<endl;
}
}
}