佳木斯集训Day6
T1还是个找规律啊,记下b的个数,然后直接*2%10000000009就好了
1 #include <bits/stdc++.h> 2 #define mo 1000000007 3 using namespace std; 4 char s[1000050]; 5 long long b,o; 6 long long ans; 7 int main() 8 { 9 cin>>s; 10 int length=strlen(s); 11 for(int i=length-1;i>=0;i--) 12 { 13 if(s[i]=='a') 14 o++; 15 } 16 if(o==length) 17 { 18 cout<<"-1"<<endl; 19 return 0; 20 } 21 for(int i=length-1;i>=0;i--) 22 { 23 if(s[i]=='b') 24 { 25 b++; 26 continue; 27 } 28 ans+=b; 29 b=b*2%mo; 30 } 31 printf("%lld",ans%mo); 32 }
T2比较好玩,我打挂了
本来的思路是不断的记二进制数,最多5次,转化五次,五个数组,然后一一比对的,理论可过,但是我挂了
正解居然是个DP???
1 #include <bits/stdc++.h> 2 #define ll long long 3 #define mo 1000000007 4 using namespace std; 5 ll b,k,sum,now; 6 int p,cnt; 7 ll ans[2000]; 8 char a[2050]; 9 ll dp[2000][2000]; 10 void solve(int x) 11 { 12 int point=x; 13 int num=0; 14 while(x) 15 { 16 if(x%2==1) 17 num++; 18 x/=2; 19 } 20 ans[point]=ans[num]+1; 21 } 22 int main() 23 { 24 cin>>a>>k; 25 int length=strlen(a); 26 if(k==1) 27 { 28 cout<<length-1<<endl; 29 return 0; 30 } 31 if(k==0) 32 { 33 cout<<1<<endl; 34 return 0; 35 } 36 if(k>5) 37 { 38 cout<<0<<endl; 39 return 0; 40 } 41 k--; 42 for(int i=2;i<=1000;i++) 43 solve(i); 44 for(int i=0;i<length;i++) 45 dp[i][0]=1; 46 for(int i=0;i<length;i++) 47 dp[i][i]=1; 48 for(int i=1;i<length;i++) 49 for(int j=1;j<=i;j++) 50 { 51 dp[i][j]=(dp[i-1][j]+dp[i-1][j-1])%mo; 52 } 53 for(int i=0;i<length;i++) 54 { 55 if(a[i]=='0') 56 continue; 57 for(int j=0;j<length-i;j++) 58 { 59 if(ans[j+now]==k) 60 { 61 sum+=dp[length-i-1][j]; 62 sum=sum%mo; 63 } 64 } 65 now++; 66 } 67 if(ans[now]==k) 68 sum++; 69 cout<<sum%mo<<endl; 70 return 0; 71 }
T3部分分的做法是树的直径,理论可得50,但是我又挂了...
现在正解也不太会,代码先空着2333