Link:http://acm.hdu.edu.cn/showproblem.php?pid=5373
The shortest problem
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 760 Accepted Submission(s): 389
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.
35 2 35 1 -1 -1
Case #1: Yes Case #2: No
官方题解:
本场最水的题,被11整除的性质是奇偶位的和之差能被11整除,然后模拟一下就好了。 然后如果用longlong的话可能会T(写的好就不会),用int就好了。(经过测试用int时间为longlong的1/4
)
我的个人解法:对于这题我完全不知道被11整除的数有这种性质,直接按题意模拟肯定不行,最后得到的数据太大了,会爆,所以只能考虑利用同余定理优化来做。
利用同余定理有如下结论:
(a+b)mod11=a mod 11+b mod 11;
(a*b)mod 11=(amod11)*(bmod11);
比如令n=123,t=2,则有如下模拟过程(红色部分表明利用同余定理优化的迭代变量):
t=0 t=1 t=2 t=……
直接模拟: 123%11 -> 1236%11 -> 123612%11 ……
利用同余定理优化的迭代模拟: 123%11 -> (1236)%11 -> ((1236)%11*100+12)%11 ……
下面用这个实例证明这种利用同余定理优化的迭代模拟与直接模拟的结果是相同的:
((1236)%11*100+12)%11 =((1236)%11*(100)%11+(12)%11 )%11=(1236*100+12)%11=123612%11
AC code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define LL long long
#define MAXN 1000010
using namespace std;
const int INF=0x3f3f3f3f;
int a[MAXN];
int main()
{
int n,t,cas,k,sum,wei;
cas=0;
while(scanf("%d%d",&n,&t)!=EOF)
{
if(n==-1&&t==-1)
{
break;
}
cas++;
if(t==0)
{
if(n%11==0)
printf("Case #%d: Yes\n",cas);
else
printf("Case #%d: No\n",cas);
}
else
{
sum=0;
k=n;
while(k)//求n的和
{
sum+=k%10;
k/=10;
}
while(t--)
{
k=sum;
wei=1;
while(k)//求sum的位数
{
wei*=10;
k/=10;
}
n=(n*wei+sum)%11;
k=sum;
while(k)//求sum的数位和
{
sum+=k%10;
k/=10;
}
}
if(n%11==0)
printf("Case #%d: Yes\n",cas);
else
printf("Case #%d: No\n",cas);
}
}
}