Number Transformation
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1635 Accepted Submission(s):
729
Problem Description
Teacher Mai has an integer x.
He does the following operations k times. In the i-th operation, x becomes the least integer no less than x, which is the multiple of i.
He wants to know what is the number x now.
He does the following operations k times. In the i-th operation, x becomes the least integer no less than x, which is the multiple of i.
He wants to know what is the number x now.
Input
There are multiple test cases, terminated by a line "0
0".
For each test case, the only one line contains two integers x,k(1<=x<=10^10, 1<=k<=10^10).
For each test case, the only one line contains two integers x,k(1<=x<=10^10, 1<=k<=10^10).
Output
For each test case, output one line "Case #k: x", where
k is the case number counting from 1.
Sample Input
2520 10
2520 20
0 0
Sample Output
Case #1: 2520
Case #2: 2600
析:有一个n,进行k次游戏,每次找出大于等于n的且能整除i(1 <= i <= k)的最小数,求最后的数
1.对于当前数xi,要求i+1的倍数,那么有(i+1)x' >= ix,则x' >= x-x/(i+1),发现x'不断减少,而当x < i+1之后,x'均不变,暴力到x < i+1即可
#include <stdio.h> #include <string.h> #include <iostream> #define ll long long using namespace std; const int N = 5000; ll n, k, i; int main(){ int ans = 1; while(~scanf("%I64d%I64d", &n, &k)){ if(n+k == 0) break; for(i = 1; i < k; i ++){ if(n < i+1) break; n -= n/(i+1); } printf("Case #%d: %I64d ", ans++, n*k); } return 0; }
2.如果想不到上面的方法,直接暴力之后发现,当k到达一定量后,x的增长成一定规律,故暴力前面部分,对之后的进行一次性计算,不过试了几次,发现N最小也只能为120000的数量级
#include <stdio.h> #include <string.h> #include <iostream> #define ll long long using namespace std; const int N = 120000; ll n, k, i; int main(){ int ans = 1; while(~scanf("%I64d%I64d", &n, &k)){ if(n+k == 0) break; for(i = 1; i <= k && i < N; i ++){ if(n%i){ n = (n/i+1)*i; } } if(i <= k){ n += (k-i+1)*((n/i+1)*i-n); } printf("Case #%d: %I64d ", ans++, n); } return 0; }