思路
看到这题的第一秒,我的脑海里就蹦出了暴力模拟。看了一眼数据范围也是直接放弃。再仔细想想,我们完全可以边输入边做。我们将每一个输入的数的上一次出现位置(未出现出现视为 0 0 0)和下标差值(第一次出现视为 0 0 0)记录下来,判断是否构成等差数列,如果无法构成就跳过,并且之后这个数再出现就直接跳过。循环结束后再分别开两个循环,一个求答案个数,一个求 x x x 和公差。
下面是代码。
#include<bits/stdc++.h>
using namespace std;
inline int Max(const int x,const int y)
{
return x>y?x:y;//不建议手打,因为我开始时打错了
}
struct k
{
int last_position,D_value;//上一次出现位置和公差
}a[100002];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n,i,j,s(0),maxn=INT_MIN,x;//j是习惯性打出,无用
bool b[100002]={};
cin>>n;
for(i=1;i<=n;++i)
{
cin>>x;
maxn=Max(maxn,x);
if(!b[x])
{
if(a[x].last_position)
{
if(!a[x].D_value)
a[x].D_value=i-a[x].last_position;
if(i-a[x].last_position!=a[x].D_value)
{
b[x]=1;
continue;
}
else a[x].last_position=i;
}
else a[x].last_position=i;
}
}
for(i=1;i<=maxn;++i)
if(a[i].last_position&&!b[i])++s;//求答案个数
cout<<s<<'\n';
for(i=1;i<=maxn;++i)//求x和公差
if(a[i].last_position&&!b[i])
cout<<i<<' '<<a[i].D_value<<'\n';//
return 0;
}