AcWing第二次热身赛

A:水题,找到不小于n的能够被4整除的最小的数。

假设n不能被4整除,那么n+1,n+2,n+3之中一定存在一个数能够被4整除。所以直接枚举即可。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 bool check(int n){
 6     int sum=0;
 7     while(n){
 8         sum+=n%10;
 9         n/=10;
10     }
11     if(sum%4==0) return true;
12     return false;
13 }
14 int main()
15 {
16     int n;
17     cin>>n;
18     while(!check(n)){
19         n++;
20     }
21     cout<<n;
22     return 0;
23 }

 

B:给定一个双端队列,插入一些数(保证无重复),同时会询问其中某些数到两端的最短距离。

因为无重复,所以我们可以直接用hash表记录值对应的位置,然后在记录左端和右端的位置,即可在O(1)的时间内获得某个数到两端的最短的距离。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <unordered_map>
 5 
 6 using namespace std;
 7 const int N=2e5+10;
 8 int hh=0,tt=-1;
 9 unordered_map<int,int> mp;//值到位置的映射
10 int main()
11 {
12     int t;
13     cin>>t;
14     while(t--){
15         char c;
16         int x;
17         cin>>c>>x;
18         if(c==L)
19             mp[x]=--hh;
20         else if(c==R)
21             mp[x]=++tt;
22         else if(c==?){
23             int pos=mp[x];
24             cout<<min(pos-hh,tt-pos)<<endl;
25         }
26     }
27     return 0;
28 }

 

C:给定一个只包含1和2的序列,能够选择任意一段连续序列反转,问最长的单调不减序列的长度为多少。

解法1:分析之后可以发现最终的答案一定是由1111122222211111122222这种子序列得来的(其中任何一段均可缺失)

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 const int N = 1e6+10;
 5 int q[N];
 6 using namespace std;
 7 int main()
 8 {
 9     int n;
10     cin>>n;
11     for(int i=0;i<n;i++) cin>>q[i];
12     int s1=0,s2=0,s3=0,s4=0;//s1表示1111的长度,s2表示11111122222的长度,s3表示11111222221111的长度,s4表示1111222211112222的长度。
13     for(int i=0;i<n;i++){
14         if(q[i]==1){
15             s1++;
16             s3=max(s2+1,s3+1);
17         }else if(q[i]==2){
18             s2=max(s1+1,s2+1);
19             s4=max(s3+1,s4+1);
20         }
21     }
22     cout<<max(max(s1,s2),max(s3,s4));
23     return 0;
24 }

 

解法2:可以将最终的答案拆成两个单调不减子序列,对于其中的一个点 i ,也就是求0~i和i+1~n-1的最长单调不减子序列。

因为序列中只有1和2,所以最长单调不减子序列可用O(n)的时间求出。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int N = 1e6+10;
 6 int n,a[N],res;
 7 int pre[N],ne[N];
 8 int cnt[3];
 9 int main()
10 {
11     //求形如11111 222222 1111111 2222222的最长长度
12     cin>>n;
13     for(int i=0;i<n;i++){
14         cin>>a[i];
15     }
16     cnt[1]=0,cnt[2]=0;
17     for(int i=0;i<n;i++){//pre为0~i的最长的单调不减子序列
18         if(a[i]==1){
19             cnt[1]++;
20             pre[i]=cnt[1];
21         }else if(a[i]==2){
22             cnt[2]=max(cnt[1],cnt[2])+1;
23             pre[i]=cnt[2];
24         }
25     }
26     
27     cnt[1]=0,cnt[2]=0;
28     for(int i=n-1;i>=0;i--){//ne为i~n-1的最长的单调不减子序列
29         if(a[i]==1){
30             cnt[1]=max(cnt[1],cnt[2])+1;
31             ne[i]=cnt[1];
32         }else if(a[i]==2){
33             cnt[2]++;
34             ne[i]=cnt[2];
35         } 
36     }
37     for(int i=0;i<n;i++) res=max(res,pre[i]+ne[i+1]);
38     cout<<res;
39     return 0;
40 }

 

AcWing第二次热身赛

上一篇:C#对象属性浅拷贝和深拷贝


下一篇:API网关系统设计