牛客小白月赛118(A~D)

A.红橙

签到题。

 1 #include <iostream>
 2 using namespace std;
 3 int main(){
 4     int x,y;
 5     cin>>x>>y;
 6     if(x==y) cout<<"Draw"<<endl;
 7     else if(y==(x+1)%3) cout<<"Hongwins"<<endl;
 8     else cout<<"chengwins"<<endl;
 9     return 0;
10 }

B.黄

给定一个数字序列,每次操作能修改一个元素为任意一个元素,问多少次操作能将序列修改为相邻的元素都互质。

显然质数只和自己的倍数不互质,对于abc,要找一个d,将b修改为和ac互质的d,这个d是绝对能够找到的,那么对于一段连续的长为n的不互质的序列,需要修改的数目为n/2。

 1 #include<iostream>
 2 #include<vector>
 3 using namespace std;
 4 typedef long long LL;
 5 const LL N = 1e5+10;
 6 LL q[N];
 7 LL gcd(LL a,LL b){
 8     return b==0?a:gcd(b,a%b);
 9 }
10 int main(){
11     LL t;
12     cin>>t;
13     while(t--){
14         LL n;
15         cin>>n;
16         vector<LL> v;
17         LL cnt=1;
18         cin>>q[0];
19         for(LL i=1;i<n;i++){
20             cin>>q[i];
21             if(gcd(q[i],q[i-1])>=2)
22                 cnt++;
23             else{
24                 if(cnt>1)
25                     v.push_back(cnt);
26                 cnt=1;
27             }
28         }
29         if(cnt>1)
30             v.push_back(cnt);
31         LL res=0;
32         for(LL i=0;i<v.size();i++)
33                 res+=v[i]/2;
34         cout<<res<<endl;
35     }
36     return 0;
37 }

C.绿

给定一个n,和一个只包含01的字符串s,s重复n次得到最终的字符串str,问str有多少单调不下降的不空子序列。简单版本s中每个字符都相同。

那么最终答案就为2^(n*s.length)-1,每个字符选或不选。

 1 #include<iostream>
 2 using namespace std;
 3 typedef long long LL;
 4 const LL MOD = 1e9+7;
 5 LL ksm(LL a,LL b){
 6     LL res=1;
 7     while(b){
 8         if(b&1)
 9             res=res*a%MOD;
10         b>>=1;
11         a=a*a%MOD;
12     }
13     return res;
14 }
15 int main(){
16     int t;
17     cin>>t;
18     while(t--){
19         LL n;
20         cin>>n;
21         string s;
22         cin>>s;
23         LL l=s.length();
24         cout<<ksm(ksm(2,n),l)%MOD-1<<endl;
25     }
26     return 0;
27 }

D.青

给定一个长度为n的数字序列表示n张试卷,需要做错其中k个,不能连续做错,最终得分为连续正确的序列的最小和值。我们的目标是选k个,使得这个最终得分最大。

首先,我们需要得出一个性质,那就是两边的必然是错的,因为比如这样的序列TTFTFTTFT,换成这样的序列FTTTFTTTF,肯定是更优的,因为最终得分是最小和值。

其次,使得最小和值最大这类问题,是显然的二分答案的题型。

 1 #include<iostream>
 2 using namespace std;
 3 typedef long long LL;
 4 const int N = 1e5+10;
 5 int n,k;
 6 LL a[N];
 7 bool check(LL s){
 8     LL cnt=0;
 9     LL sum=0;
10     for(int i=1;i<n-1;i++){
11         sum+=a[i];
12         if(sum>=s){
13             sum=0;
14             cnt++;
15             i++;
16         }
17     }
18     return cnt>=k-1;
19 }
20 int main(){
21     int t;
22     cin>>t;
23     while(t--){
24         cin>>n>>k;
25         LL total=0;
26         for(int i=0;i<n;i++){
27             cin>>a[i];
28             total+=a[i];
29         }
30         if(k==0) cout<<total<<endl;
31         else if(k==1) cout<<max(total-a[0],total-a[n-1])<<endl;
32         else if(k==2) cout<<total-a[0]-a[n-1]<<endl;
33         else{
34             LL l=0,r=total;
35             while(l<r){
36                 LL mid=l+r+1>>1;
37                 if(check(mid))
38                     l=mid;
39                 else
40                     r=mid-1;
41             }
42             cout<<l<<endl;
43         }
44     }
45     return 0;
46 }

 

posted on 2025-06-14 11:24  greenofyu  阅读(29)  评论(0)    收藏  举报