Problem Description
In this problem, we should solve an interesting game. At first, we have an integer n, then we begin to make some funny change. We sum up every digit of the n, then insert it to the tail of the number n, then let the new number be the interesting number n. repeat it for t times. When n=123 and t=3 then we can get 123->1236->123612->12361215.
Input
Multiple input. We have two integer n (0<=n<= 104 ) , t(0<=t<= 105 ) in each row. When n==-1 and t==-1 mean the end of input.
Output
For each input , if the final number are divisible by 11, output “Yes”, else output ”No”. without quote.
Sample Input
35 2 35 1 -1 -1
Sample Output
Case #1: Yes Case #2: No
题意:将一个数的每一位相加,得到的和放到该数的后面,经过t次后。以最后数对11进行整除,若可以整除输出Yes否则No
该题首先思路是用数组将将运算得的数存起来,最后将该数进行大数取余。这是最直观的想法,但是这种方法必定会超时,因为首先需要经过t次每位的相加,然后存到数组里,而该数又与平常的大数加法不同,得到的数放在最后的。所以以直观方法去写复杂度会很高。
优化方法:其实没必要将得到的数字存起来,由大数取余运算可知,需要从数字的最大位开始取余,由于该题对11取余,所以需要对最大两位进行取余然后将余数放回数组中,再对最大的两位取余,一直到数组最后,若最后的值为0则可以整除。而这种方法由于该题目关系,每进行一次各位求和(sum)就可以对sum进行取余,然后求得的和放到数组最后便成为了下次取余的目标。以此类推,完成大数取余的过程并不需要储存到数组中。一边累加一边完成。由于累加得到的值会有多位,所以需要计算sum的位数。不懂就直接看代码吧
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
int mul,top,sum;
int main()
{
int n,t,m;
int i,j=0,k;
while (scanf("%d%d",&n,&t),n!=-1||t!=-1)
{
j++;
top=0;sum=0;
k=n%11;
while (t--)
{
mul=1;
while (n)
{
sum += n%10;
n /= 10;
}
n=m=sum;
while(m)
{
m /= 10;
mul *= 10;
}
k= (k*mul+sum)%11;
}
if(k==0)
printf("Case #%d: Yes\n",j);
else
printf("Case #%d: No\n",j);
}
return 0;
}