1
110
2
1100
3
110
YES
YES
N
暴力会超时:
其实此题有规律:
能被2的N次方的数整除的数的特征
如果一个数末N位能被2的N次方的数整除,那么这个数就能被2的N次方的这个数整除。
如能被8(2的3次方)整除的数的特征:这个数字的末三位能被8整除。
能被11整除的数的特征
把一个数由右边向左边数,将奇位上的数字与偶位上的数字分别加起来,再求它们的差,如果这个差是11的倍数(包括0),那么,原来这个数就一定能被11除.
例如:判断491678能不能被11整除.
—→奇位数字的和9+6+8=23
—→偶位数位的和4+1+7=12
23-12=11 因此,491678能被11整除. 这种方法叫"奇偶位差法".
参考代码:
<span style="font-family:Microsoft YaHei;">/************** NYOJ 1086 Times:136ms #include<stdio.h> #include<string.h> char str[10000005]; int fun() { int i,sum=0,len=strlen(str); for(i=0; i<len; i++) { if(i%2) sum+=(str[i]-'0'); else sum-=(str[i]-'0'); } if(sum%11==0) return 1; else return 0; } int gun(int n) { int i,len=strlen(str); long long sum=0,a=1; for(i=0; i<n; i++) a*=2; for(i=len-n; i<len; i++) sum=sum*10+str[i]-'0'; if(sum%a==0) return 1; else return 0; } int main() { int n; while(scanf("%d%s",&n,&str)!=EOF) { if(fun()&&gun(n)) printf("YES\n"); else printf("NO\n"); } return 0; }</span>学长的代码:
<span style="font-family:Microsoft YaHei;">#include<stdio.h> #include<cstring> using namespace std; char s[1000005]; int main() { int n; while(~scanf("%d%s",&n,s)) { int t=strlen(s); long long int c=(1<<n)*11,sum=0; for(int i=0; i<t; i++) sum=(sum*10+s[i]-'0')%c; printf(sum?"NO\n":"YES\n"); } return 0; } </span>
<span style="font-family:Microsoft YaHei;"> long long int c=(1<<n)*11,sum=0;表示2的n 次方,用了<<位运算,</span>