今天比赛太热血了!虽然最后排名还是那个屎样。但是打得很开心就够了!
题意:
给一个整数x,对它进行k次操作,第i次操作把x变成不小于x的最小的i的倍数,问这个数变成多少了。
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.
本来我感觉求出一个x对于i的倍数以后就不会变了,兴冲冲地跑去跟队友说,然后被嘲讽了。。
仔细一想,虽然不是一开始就可以确定这个倍数,但是当这个倍数小于等于i以后,就不会再变小了,这个可以分类讨论加数学归纳法证明。然后设这个倍数为m,i*m==x恒成立,所以只要i>=sqrt(x)就可以找到稳定的m,x本身最大是10^10,虽然在扩大,但是i循环到sqrt(x)就可以了,x扩大的数量最大不超过i,因此只要扩大x的操作足够快,跑i的循环完全没问题。扩大x则只需要判断当前x是否被i整除,不行可以用O(1)操作直接扩大。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
long long x,k;
int main(){
int cs=0;
while(scanf("%lld%lld",&x,&k)!=EOF){
if(!x&&!k) break;
long long m;
long long i;
for(i=1;i<=sqrt(x+0.5)+5;++i){
if(x%i) x=(x/i+1)*i;
if(i==k){
++i;
break;
}
}
m=x/(i-1);
printf("Case #%d: %lld\n",++cs,k*m);
}
return 0;
}