大致题意:
给出一个f(x)=an*x^n+......+a1*x+a0,看能否找到一个x使得f(x)%(pri*pri)==0成立,其中pri为一个素数(pri<=10000); abs(an)<=100; 当f(x)系数的个数n>=3时,abs(ai)<10000, 否则abs(ai)<=100000000 (i
输入
第一行输入测试用例的个数,
第二行的第一个数表示f(x)系数的个数,即为n;接着后面输入an~a0 n个整数;最后输入一个素数pri。
输出
输出任意一个使得f(x)%(pri*pri)成立的x,否则输出"No solution!"。
解题思路:
如果存在一个x使得f(x)%(pri*pri)==0成立,那么该x一定能使f(x)%pri==0成立;因此f(x)%pri==0是f(x)%(pri*pri)==0成立的必要不充分条件;
因此要找到一个使得f(x)%(pri*pri)==0成立的x,首先得找到一个使得f(x1)%pri==0成立的x1;然后再从x1~pri*pri之间开始枚举,每次加pri(每次加pri是为了使f(x)每次增加的值是pri的倍数,从而保证f(x)%pri==0能够成立),看能否找到一个x使得f(x)%pri*pri==0成立。
如果在1到pri*pri之间没有找到一f(x)%(pri*pri)==0成立的x,那么就不存在一个x使得f(x)%(pri*pri)==0成立。
解释:
对于任意一个大于pri*pri的数n,我们都可以将其成写n=(pri*pri)*t+k的形式,其中t为整数,k<=pri*pri;那么f(pri*pri*t+k)的值就相当于在f(k)的值的基础上增加了pri*pri的倍数;
所以若f(k)%pri*pri==0不成立,则f(pri*pri*t+k)%pri*pri==也不会成立;因此若在1到pri*pri之间不能找到一个x使得 f(x)%pri*pri==0成立,那么就不存在一个x使得f(x)%pri*pri==0成立
代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int t,n,i,j,k,x1,z;
int a[7],flag[100005];//a数组用来保存ai,flag数组用来保存用来保存能使f(x1)%pri==0成立的x1
int pri;
long long sum,x;
scanf("%d",&t);//输入测试用例的个数
for(z=1;z<=t;z++)
{
k=0;
memset(flag,-1,sizeof(flag));
scanf("%d",&n);//输入f(x)系数的个数
for(i=n; i>=0; i--)
scanf("%d",&a[i]);//输入an到a0
scanf("%d",&pri);//输入一个素数
for(i=1; i<=pri; i++)//枚举1到pri之间的数,找出使得f(x)%prii==0成立的x1
{
x=i;
sum=a[0];
for(j=1; j<=n; j++)//对于每个数值x来计算f(x)的数值
{
sum+=a[j]*x;
if(sum>=pri*pri)sum%=(pri*pri);//当sum的数值大于pri*pri时,进行取余
x*=x;
}
if(sum%pri==0)flag[k++]=i;//保存每个使得f(x1)%pri==0成立的x1
if(sum%(pri*pri)==0)//判断在1到pri之间是否找到了一个x使得f(x)%pri*pri==0成立
break;
}
if(i<=pri)printf("Case #%d: %d\n",z,i);//如果找到符合条件的x则输出来
else if(flag[0]!=-1)//当在1到pri之间没找到一个使得f(x)%pri*pri==0成立的x时
{
for(x1=0; x1<k; x1++)//利用上一步保存下来的x1,从x1+pri开始枚举,每次加上一个pri
// 枚举到pri*pri为止,看能否找到一个符合条件的x
{
for(i=flag[x1]+pri; i<=pri*pri; i+=pri)//对于每个x1开始进行枚举
{
x=i;
sum=a[0];
for(j=1; j<=n; j++)//对于每个枚举出来的x,代入f(x)中进行运算
{
sum+=a[j]*x;
if(sum>=pri*pri)sum%=(pri*pri);
x*=x;
}
if(sum%(pri*pri)==0)//判断枚举出来的x是否符合条件
break;
}
if(sum%(pri*pri)==0)//判断枚举出来的x是否符合条件,如果符合则结束枚举
break;
}
if(i<=pri*pri)printf("Case #%d: %d\n",z,i);//如果找到符合条件的x则输出来
else printf("Case #%d: No solution!\n",z);//否则输出No solution!
}
else printf("Case #%d: No solution!\n",z);//当在1到pri之间没有找到了一个x使得f(x)%pri==0成立时
}
return 0;
}