题意:给你一个数列问有没有一个数m,可以让数列所有数除m取余之后变成一个回文串。输出最大的m,如果m可以取任意值输出-1。
条件:1 数列所有数除m取余之后变成一个回文串
思路:对取余敏感在把它想象成m*n(m的倍数)+k(余数),这个时候如果取余要变成回文串,那么例如第一个数和最后一个数就满足相减为m的倍数。那么条件1就变成:所有回文位置的数相减为m的倍数,中间的可以不用考虑。(有一个特殊情况就是相减之后都为0的,可以是任意的)这个时候只需要求相减后的最大公约数。
代码:
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <cstring>
using namespace std;
const int maxn=1e5+5;
int num[maxn];
int gcd(int a,int b)//gcd最大公约数
{
return b==0?a:gcd(b,a%b);
}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i]);
}
for(int i=1;i<=n/2;i++)//求相减后的值
{
num[i]=abs(num[n-i+1]-num[i]);
}
int flag=0;
for(int i=1;i<=n/2;i++)//如果相减后全部都为0
{
if(num[i]!=0)
flag=1;
}
if(flag==0)
{
printf("-1\n");
return 0;
}
//如何求多个数的最大公约数
int k=num[1];
for(int i=2;i<=n/2;i++)
{
k=gcd(k,num[i]);
}
printf("%d\n",k);
return 0;
}
总结:1 对除余取模化为m*n(m的倍数)+k(余数)的思维不够敏感和有经验。2 学习了一下求公约数