AcWing周赛 40

A:签到题,直接模拟即可

题目地址:https://www.acwing.com/problem/content/4308/

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <set>
 5 
 6 using namespace std;
 7 const int N=1010;
 8 int f[N];
 9 set<int> S;
10 int main()
11 {
12     f[0]=f[1]=1;
13     int n;
14     cin>>n;
15     S.insert(1);
16     for(int i=2;f[i-1]<=n;i++){
17         f[i]=f[i-1]+f[i-2];
18         S.insert(f[i]);
19     }
20     string res="";
21     for(int i=1;i<=n;i++){
22         if(S.count(i)){
23             res+='O';
24         }else{
25             res+='o';
26         }
27     }
28     cout<<res;
29     return 0;
30 }

 

B:题目地址:https://www.acwing.com/problem/content/4309/

考试时的想法是直接爆搜,将输入分为两类,可以保持原大小的 和 有重合的,然后美剧每一个有重合的数据,找到其应该变成的大小,时间复杂度为O(n^2),用unordered_set能够水过去,但是不够完美。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <unordered_set>
 5 using namespace std;
 6 unordered_set<int> S;
 7 vector<int> w;
 8 int main()
 9 {
10     int n;
11     cin>>n;
12     for(int i=0;i<n;i++){
13         int t;
14         cin>>t;
15         if(S.count(t)) w.push_back(t);
16         else S.insert(t);
17     }
18     int res=0;
19     while(w.size()){
20         int t=w.back();
21         w.pop_back();
22         for(int i=t;;i++){
23             if(!S.count(i)){
24                 S.insert(i);
25                 res+=i-t;
26                 break;
27             }
28         }
29     }
30     cout<<res;
31     return 0;
32 }

这一题是存在贪心解法的(取自yxc),首先将输入排序。

可以证明最优解可以是有序的,而我们的贪心方法就是 f [ i ] = max ( f [ i - 1 ] +1 ,  q [ i ] )

首先因为贪心解一定是一种解,所以贪心解>=最优解。

以下运用反证法真名贪心解<=最优解

假设贪心解>最优解

我们找到贪心解与最优解第一个不相等的地方(因为两者都是有序的)

 

只有可能是上图的情况,故贪心解<=最优解

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <unordered_set>
 5 using namespace std;
 6 const int N = 3010;
 7 int q[N];
 8 int f[N];
 9 int main()
10 {
11     int n;
12     cin>>n;
13     for(int i=0;i<n;i++) cin>>q[i];
14     sort(q,q+n);
15     int res=0;
16     f[0]=q[0];
17     for(int i=1;i<n;i++){
18         f[i]=max(f[i-1]+1,q[i]);
19         res+=f[i]-q[i];
20     }
21     cout<<res;
22     return 0;
23 }

 

 C:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 int cnt[10];
 6 string get_min(int x){
 7     string res=to_string(x);
 8     cnt[x]--;
 9     for(int i=0;i<10;i++){
10         for(int j=0;j<cnt[i];j++){
11             res+=to_string(i);
12         }
13     }
14     cnt[x]++;
15     return res;
16 }
17 int main(){
18     string a,b;
19     cin>>a>>b;
20     if(a.size()<b.size()){
21         sort(a.begin(),a.end(),greater<char>());
22         cout<<a;
23     }else{
24         for(auto c:a) cnt[c-'0']++;
25         string res="";
26         for(int i=0;i<a.size();i++){
27             for(int j=9;j>=0;j--){
28                 if(cnt[j] && res+get_min(j) <= b){
29                     res+=to_string(j);
30                     cnt[j]--;
31                     break;
32                 }
33             }
34         }
35         cout<<res;
36     }
37     return 0;
38 }

 

posted on 2022-02-26 22:21  greenofyu  阅读(34)  评论(0编辑  收藏  举报