Ignatius's puzzle
no exists that a,then print "no".
11 100 9999
22 no 43
思路1:给出K,满足f(x)%65==0 的 a的最小值。
其中:65=13*5。要使f(x)是65的倍数,只需要f(x)是5和13的倍数即可。先来分析13的。
若f(x)是13的倍数,
有5*x^13+13*x^5+k*a*x % 13 == 0,其中13*x^5项显然不用考虑。
则只需5*x^13 + k*a*x是13的倍数,即x*(5*x^12+k*a)是13的倍数。若x是13的倍数,不用考虑。
若x不是13的倍数,则x一定与13互素,因为EulerPhi(13) == 12,从而x^12 % 13 == 1。(费马小定理)
所以可知5*x^12 % 13 == 5。
因为要让任意x满足条件,则括号内必为13的倍数,有(k*a+5 )% 13 == 0,则k*a % 13 == 8。
同理可得k*a % 5 == 2。
因此,若k为5或13的倍数,a一定无解,否则,一定有解。
根据k%5的结果,可能为1、2、3、4,a应分别取5n+2,5n+1,5n+4,5n+3。当a取上述值时,如果k*a%13==0 此时a就是要求的最小值
PS:费马小定理: 假如p是质数,且(a,p)=1,那么 a^(p-1) ≡1(mod p) 假如p是质数,且a,p互质,那么 a的(p-1)次方除以p的余数恒等于1 。
code:
#include<bits/stdc++.h>
int main()
{
int k,c[6],a;
c[1]=2,c[2]=1,c[3]=4,c[4]=3;
while(scanf("%d",&k)!=EOF)
{
if(k%5==0||k%13==0)
{
printf("no\n");
continue;
}
a=c[k%5];
while(1)
{
if(k*a%13==8)
{
printf("%d\n",a);
break;
}
else
a+=5;
}
}
return 0;
}
思路2:打表找规律。
(5*x^13+13*x^5)%65 每65成循环。要使结果成立(k*a*x)%65,也得每65个循环,且a的值在0-64之间
code:
#include<bits/stdc++.h>
using namespace std;
int a[1000];
int main()
{
for(int x=1;x<=65;x++)
a[x]=(5*x%65*x*x%65*x*x%65*x*x%65*x*x%65*x*x%65*x*x%65+13*x%65*x*x%65*x*x%65)%65;
int k;
while(scanf("%d",&k)==1)
{
int ok,ans;
for(int aa=0;aa<65;aa++)
{
ok=1;
for(int i=1;i<=65;i++)
{
if((a[i]+k*i%65*aa%65)%65!=0)
{
ok=0;
break;
}
}
if(ok)
{
ans=aa;
break;
}
}
if(ok)
printf("%d\n",ans);
else
printf("no\n");
}
return 0;
}
思路3:
数学归纳法,将f(x+1)展开 (本渣不会)能知道 当 18+k*a能被65整除时 求得解
code:
#include<iostream>
using namespace std;
int main()
{
int k,i;
while(scanf("%d",&k)!=EOF)
{
for(i=1;i<=10000;i++)
{
if((18+k*i)%65==0){printf("%d\n",i);break;}
}
if(i>10000)printf("no\n");
}
return 0;
}
思路4:数字很和谐 你可以猜猜看 思路3的答案:
参考:http://www.cnblogs.com/g0feng/archive/2012/08/23/2652996.html