hdu 4952

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.
 

 

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).
 

 

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\n", ans++, n*k);
    }
    return 0;
}
View Code

 

  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\n", ans++, n);
    }
    return 0;
}
View Code

 

 
posted @ 2020-05-06 19:40  傲-寒  阅读(142)  评论(0编辑  收藏  举报