1. 程式人生 > 實用技巧 >JYU程式設計決賽題解與思考(更新中)

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的倍數。

證明:

對於二進位制數的偶數位:

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的倍數。