hdu 1098 Ignatius's puzzle

原题链接

Ignatius's puzzle

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7532    Accepted Submission(s): 5231


Problem Description
Ignatius is poor at math,he falls across a puzzle problem,so he has no choice but to appeal to Eddy. this problem describes that:f(x)=5*x^13+13*x^5+k*a*x,input a nonegative integer k(k<10000),to find the minimal nonegative integer a,make the arbitrary integer x ,65|f(x)if
no exists that a,then print "no".

 

Input
The input contains several test cases. Each test case consists of a nonegative integer k, More details in the Sample Input.
 

Output
The output contains a string "no",if you can't find a,or you should output a line contains the a.More details in the Sample Output.
 

Sample Input
  
  
11 100 9999
 

Sample Output
  
  
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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值