Ignatius's puzzle
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4513 Accepted Submission(s): 3068
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".
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
Author
eddy
Statistic | Submit | Discuss | Note
这题实际上是求:对给定的k,求a满足65|(18+k*a),以下说明。
设g(x)=5*x^13+13*x^5,对于输入的k,若存在a使得f(x)对任意x均能被65整除,x=1时有
f(1)= g(1)+a×k = 65×r(1)········(1)
对任意x=n,有
f(1)= g(n)+a×n×k= 65×r(n)········(2)
其中r(i)是x= i 时f(i)除以65的商,显然只要这样的r(i)存在就有65|f(i)
由(1)×n - (2)得:n×g(1)=65×n×r(1)-65×r(n)
由上式可见,由于g(1)=18已经确定,只要确定r(1),对任意n,r(n)就能确定,隐含意思是,只要r(1)存在,r(n)就存在,于是只要65|f(1)就有65|f(n)。
于是问题转化为:对给定的k,求a满足65|(18+k*a)
我的做法很笨拙,但能保证AC,先枚举小于整数maxn的65的倍数,再枚举a的取值,如果在18+k*a超过maxn之前存在a的某一取值使得65|(18+k*a),则成功找到a,否则a不存在。
那么maxn如何确定呢?我是先取maxn为一个较大的值,然后遍历k=1:9999,记录出现的65|(18+k*a)满足时(18+k*a)的最大值,然后取maxn=该值。
AC Code:
1 #include <iostream> 2 #include <fstream> 3 #include <string> 4 #include <set> 5 #include <map> 6 #include <vector> 7 #include <stack> 8 #include <queue> 9 #include <cmath> 10 #include <cstdio> 11 #include <cstring> 12 #include <algorithm> 13 #include <utility> 14 using namespace std; 15 #define ll long long 16 #define cti const int 17 #define ctll const long long 18 #define dg(i) cout << '*' << i << endl; 19 20 const int maxn = 637651; 21 map<int, bool> m; 22 23 void Init() 24 { 25 int s = 65; 26 while(s < maxn) 27 { 28 m[s] = true; 29 s += 65; 30 } 31 } 32 33 int main() 34 { 35 int a, k; 36 Init(); 37 while(scanf("%d", &k) != EOF) 38 { 39 int s = 0; 40 for(a = 1; s < maxn; a++) 41 { 42 s = 18 + a * k; 43 if(m[s]) 44 break; 45 } 46 if(s < maxn) printf("%d\n", a); 47 else puts("no"); 48 } 49 return 0; 50 }