Codeforces Round #661 (Div. 3)(A B C D E)

 

rank: 974

rating: 1503 + 42

 

A:Remove Smallest

代码:

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define MOD 998244353 
 4 #define INF 0x3f3f3f3f
 5 #define mem(a,x) memset(a,x,sizeof(a))  
 6 #define _for(i,a,b) for(int i=a; i< b; i++)
 7 #define _rep(i,a,b) for(int i=a; i<=b; i++)
 8 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 9 using namespace std;
10  
11 int main()
12 {
13     int n,t;
14     int a[105];
15     cin>>t;
16     while(t--){
17         cin>>n;
18         for(int i=1;i<=n;i++){
19             scanf("%d",&a[i]);
20         }
21         sort(a+1,a+n+1);
22         int k=1;
23         for(int i=1;i<n;i++){
24            if(a[i+1]-a[i]>1){
25              k=0;
26              break;
27            }
28         }
29         if(k){
30             cout<<"YES"<<endl;
31         }else{
32             cout<<"NO"<<endl;
33         }
34     }
35     return 0;
36 }
View Code

 

B:Gifts Fixing

思路:找到A和B序列中的最小值,对于每个a[i]b[i],贡献是max(a[i]-mina,b[i]-minb)。

代码:

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define MOD 998244353 
 4 #define INF 0x3f3f3f3f
 5 #define mem(a,x) memset(a,x,sizeof(a))  
 6 #define _for(i,a,b) for(int i=a; i< b; i++)
 7 #define _rep(i,a,b) for(int i=a; i<=b; i++)
 8 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 9 using namespace std;
10  
11 ll a[105];
12 ll b[105];
13 int main()
14 {
15     int n,t;
16     cin>>t;
17     while(t--){
18         cin>>n;
19         ll mina=1000000005;
20         ll minb=1000000005;
21         for(int i=1;i<=n;i++){
22             scanf("%lld",&a[i]);
23             mina=min(a[i],mina);
24         }
25          for(int i=1;i<=n;i++){
26             scanf("%lld",&b[i]);
27             minb=min(b[i],minb);
28         }
29         ll sum=0;
30         for(int i=1;i<=n;i++){
31             ll da=a[i]-mina;
32             ll db=b[i]-minb;
33             ll xx=min(da,db);
34             sum+=xx;
35             da-=xx;
36             db-=xx;
37             //cout<<da<<" "<<db<<endl;
38             if(da!=0){
39                 sum+=da;
40             }else{
41                 sum+=db;
42             }
43         }
44         cout<<sum<<endl;
45     }
46     return 0;
47 }
View Code

 

C: Boats Competition

思路:就是暴力枚举每种可能重量下的最大值。

代码:

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define MOD 998244353 
 4 #define INF 0x3f3f3f3f
 5 #define mem(a,x) memset(a,x,sizeof(a))  
 6 #define _for(i,a,b) for(int i=a; i< b; i++)
 7 #define _rep(i,a,b) for(int i=a; i<=b; i++)
 8 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 9 using namespace std;
10  
11 int w[1005];
12 int sum[1005];
13 int main()
14 {
15     int n,t;
16     cin>>t;
17     while(t--){
18         cin>>n;
19         mem(sum,0);
20         for(int i=1;i<=n;i++){
21            scanf("%d",&w[i]);
22         }
23         sort(w+1,w+n+1);
24         int num=0;
25         for(int i=w[n]+w[n-1];i>=w[1]+w[2];i--){
26             int pp=0;
27             mem(sum,0);
28             for(int j=1;j<=n;j++){
29                 sum[w[j]]++;
30             }
31             for(int j=1;j<=n;j++){
32                 if(i-w[j]>=1){
33                 if((sum[i-w[j]]>=1&&w[j]!=i-w[j]&&sum[w[j]]>=1)||(sum[i-w[j]]>=2&&w[j]==i-w[j])){
34                     pp++;
35                     sum[w[j]]--;
36                     sum[i-w[j]]--;
37                 }
38                 }
39             }
40             //cout<<i<<" "<<pp<<endl;
41             num=max(num,pp);
42         }
43         cout<<num<<endl;
44     }
45     return 0;
46 }
View Code

 

D:Binary String To Subsequences

思路:贪心。如果当前位置为 1 ,找前面已经是否存在结尾是 0 的子串,如果不存在则增加子串序号。用 k0 和 k1两个vector 储存结尾是0 和 1 两种情况的子串编号,即如果没有这种情况的子串,则增加子串,否则就把这个字符加入一个已有的子串。

代码:

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define MOD 998244353 
 4 #define INF 0x3f3f3f3f
 5 #define mem(a,x) memset(a,x,sizeof(a))  
 6 #define _for(i,a,b) for(int i=a; i< b; i++)
 7 #define _rep(i,a,b) for(int i=a; i<=b; i++)
 8 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 9 using namespace std;
10  
11 string s;
12 int a[200005];
13 int k[200005];
14 int main()
15 {
16     int n,t;
17     cin>>t;
18     while(t--){
19         cin>>n;
20         cin>>s;
21         vector<int>k1;
22         vector<int>k0;
23         k1.clear();
24         k0.clear();
25         int num=1;
26         a[0]=1;
27         if(s[0]=='1'){
28            k1.push_back(1);
29         }else{
30            k0.push_back(1);
31         }
32         for(int i=1;i<s.size();i++){
33            if(s[i]=='1'){
34               if(k0.size()){
35                  a[i]=k0[0];
36                  k1.push_back(k0[0]);
37                  k0.erase(k0.begin());
38               }else{
39                  num++;
40                  a[i]=num;
41                  k1.push_back(num);
42               }
43            }else{
44               if(k1.size()){
45                  a[i]=k1[0];
46                  k0.push_back(k1[0]);
47                  k1.erase(k1.begin());
48               }else{
49                  num++;
50                  a[i]=num;
51                  k0.push_back(num);
52               }
53            }
54         }
55         cout<<num<<endl;
56         for(int i=0;i<s.size();i++){
57             if(i==s.size()-1){
58                 cout<<a[i]<<endl;
59             }else{
60                 cout<<a[i]<<" ";
61             }
62         }
63     }
64     return 0;
65 }
View Code

 

E1. Weights Division (easy version)

题意:给你一棵树,树的每条边都有权值,设这棵树的重量是从根走向每片叶子所获得的权值的总和。给你一个值S,你可以对任意一条路径操作,是的这条路径的权值  w[ i ] = w[ i ] /2 (向下取整)。问你最少需要几步操作就可以让树的重量小于等于S。

思路:贪心。一开始树的重量是确定的,就是每条边和该边使用次数的乘积之和。所以我们首先要计算出所有边的使用次数,我们用cnt 来表示。我们可以用 dfs 预处理每条边的使用次数。然后把对每条边的操作时的改变量放入一个 set 中,由于set 有自动排序功能,因此每一步操作只需要把set 末尾的元素删去,再用sum 减去这个值,然后再插入 某个w[ i ]更新后的值,这样可以使每次减去的数最大,也就可以使步数最少。

代码:

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define MOD 998244353 
 4 #define INF 0x3f3f3f3f
 5 #define mem(a,x) memset(a,x,sizeof(a))  
 6 #define _for(i,a,b) for(int i=a; i< b; i++)
 7 #define _rep(i,a,b) for(int i=a; i<=b; i++)
 8 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 9 using namespace std;
10  
11 int w[100005];
12 int cnt[100005];
13 vector<pair<int,int>>g[100005];
14 int n;
15 ll s;
16 void dfs(int x,int fa)
17 {
18     if(g[x].size()==1){
19         cnt[fa]=1;
20     }
21     for(auto [to,id]:g[x]){
22         if(id==fa)continue;
23         dfs(to,id);
24         if(fa!=-1)cnt[fa]+=cnt[id];
25     }
26 }
27 ll getnum(int id)
28 {
29     return  (ll)w[id]*cnt[id]-(ll)(w[id]/2)*cnt[id];
30 }
31 int main()
32 {
33     int t;
34     cin>>t;
35     while(t--){
36         mem(cnt,0);
37         mem(w,0);
38         scanf("%d %lld",&n,&s);
39         for(int i=0;i<=n;i++){
40             g[i].clear();
41         }
42         for(int i=0;i<n-1;i++){
43             int x,y;
44             cin>>x>>y>>w[i];
45             x--;
46             y--;
47             g[x].push_back({y,i});
48             g[y].push_back({x,i});
49         }
50         dfs(0,-1);
51         set<pair<ll,int>>st;
52         st.clear();
53         ll sum=0;
54         for(int i=0;i<n-1;i++){
55            long long num=(ll)w[i]*(ll)cnt[i];
56            st.insert({getnum(i),i});
57            sum+=num;
58         }
59         int step=0;
60         while(s<sum){
61             int id=st.rbegin()->second;
62             sum-=getnum(id);
63             set<pair<ll,int> >::iterator ip;
64             ip=st.end();
65             st.erase(--ip);
66             w[id]=w[id]/2;
67             st.insert({getnum(id),id});
68             step++;
69         }
70         cout<<step<<endl;
71     }
72     return 0;
73 }
View Code

 

E2:0

F:0

  

 

posted @ 2020-08-06 15:17  hachuochuo  阅读(319)  评论(0编辑  收藏  举报