JYU程序设计决赛题解与思考(更新中)
被绿的小华

题目大意就是给出一个01串表示的二进制数是否为3的倍数。
方法1:暴力
直接用快速幂暴力求解,求解的过程中同时模3。
1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #define MAXN 10000 8 #define int long long 9 #define mod 3 10 using namespace std; 11 int n,m,ans=0; 12 int a[MAXN]; 13 inline int pow_(int x,int n){ 14 int cnt=1; 15 while(n){ 16 if(n&1) 17 cnt=cnt*x%mod; 18 x=x*x%mod; 19 n>>=1; 20 } 21 return cnt%mod; 22 } 23 signed main() 24 { 25 string s; 26 cin>>s; 27 for(int i=s.size()-1,j=0;i>=0;i--,j++){ 28 if(s[i]=='1'){ 29 ans=ans+pow_(2,j); 30 ans%=mod; 31 } 32 } 33 if(ans==0) cout<<"Y"<<endl; 34 else cout<<"N"<<endl; 35 return 0; 36 }
方法2:数学
二进制数的奇数位1的个数与偶数位1的个数的差能被3整除,则这个数是3的倍数。
1 #include<iostream> 2 #include<cstdio> 3 #include<list> 4 #include<string> 5 #include<map> 6 #include<set> 7 #include<queue> 8 #include<stack> 9 #include<cmath> 10 #include<ctime> 11 #include<algorithm> 12 #include<cstring> 13 #define sc scanf 14 #define pr printf 15 #define MAXN 10001 16 #define INF 9999999999 17 #define endd puts(""); 18 #define int long long 19 #define il inline 20 #define PI 3.1415926535898 21 #define INF_MIN -214783647 22 using namespace std; 23 il int read() { 24 int s = 0, f = 1; 25 char ch = getchar(); 26 while (ch<'0'||ch>'9') { if (ch == '-') f = -1; ch = getchar(); } 27 while (ch>='0'&&ch<='9') { s = s * 10 + ch - '0'; ch = getchar(); } 28 return s * f; 29 } 30 /******************************head*****************************************/ 31 int pow_(int a,int n){ 32 int cnt=1; 33 while(n){ 34 if(n&1) 35 cnt=cnt*a; 36 a=a*a; 37 n>>=1; 38 } 39 return cnt; 40 } 41 signed main() 42 { 43 int num1=0,num2=0; 44 string s; 45 cin>>s; 46 for(int i=s.size()-1;i>=0;i--){ 47 if(s[i]=='1'){ 48 if(i&1) num1++; 49 else num2++; 50 } 51 } 52 if(abs(num1-num2)%3==0) cout<<"Y"; 53 else cout<<"N"; 54 return 0; 55 }
证明:
对于二进制数的偶数位:
2^0%3=1;
2^2=2^0*4;
2^2%3=(2^0%3)*(4%3)=(2^0%3)*1=2^0%3=1;
则2^2%3==2^0%3;
2^4%3=(2^2%3)*(4%3)=(2^2%3)*1=2^2%3=2^0%3=1;
则2^4%3==2^2%3==2^0%3;
以此类推
(2^2n)%3=2^(2(n-1))%3*(4%3)=2^(2(n-1))%3*1=2^(2(n-2))%3*(4%3)……=2^(2(n-n))%3*4%3=2^0*(4%3)=2^0*1=1*1;
得(2^2n)%3=2^0*1=1;
而二进制数的奇数位同理可证得(2^(2n+1))%3=2^1%3=2;
从而得出一个二进制数的奇数位%3为2,二进制数的偶数位%3为1;
奇数位1的个数与偶数位1的个数的差有两种情况:
(1)奇数位1的个数与偶数位1的个数相等;
若一个二进制数有n个奇数位的1,m个偶数位的1,且n=m,由上面证得的结论可知二进制数的奇数位%3为2,偶数位%3为1;
则这个二进制数%3的值为n(1+2)%3=3n%3=0,这个二进制数能被3整除;
(2)奇数位1的个数与偶数位1的个数不等;
若一个二进制数有n个奇数位的1,m个偶数位的1,且n>m,由上面证得的结论可知二进制数的奇数位%3为2,偶数位%3为1;
则这个二进制数%3的值为m(1+2)%3+(n-m)*2%3,若n-m%3==0,则(n-m)*2%3==0,可得结论若奇数位的1大于偶数位的1的个数且个数差为3的倍数,则该二进制数是3的倍数;
若一个二进制数有n个奇数位的1,m个偶数位的1,且n<m,由上面证得的结论可知二进制数的奇数位%3为2,偶数位%3为1;
则这个二进制数%3的值为n(1+2)%3+(n-m)*1%3,若n-m%3==0,则(n-m)*1%3==0,可得结论若奇数位的1小于偶数位的1的个数且个数差为3的倍数,则该二进制数是3的倍数;
综上所述可证得:二进制数的奇数位1的个数与偶数位1的个数的差能被3整除,则这个数是3的倍数。

浙公网安备 33010602011771号