Codeforces Round 652 Div2

Codeforces Round 652 Div2

Round652的题感觉就是想到了就容易实现,代码不是很复杂。但就这变成了打的最差的一次。。这里记录一下BCD题。

B题 AccurateLee
Lee was cleaning his house for the party when he found a messy string under the carpets. Now he’d like to make it clean accurately and in a stylish way…

The string 𝑠 he found is a binary string of length 𝑛 (i. e. string consists only of 0-s and 1-s).

In one move he can choose two consecutive characters 𝑠𝑖 and 𝑠𝑖+1, and if 𝑠𝑖 is 1 and 𝑠𝑖+1 is 0, he can erase exactly one of them (he can choose which one to erase but he can’t erase both characters simultaneously). The string shrinks after erasing.

Lee can make an arbitrary number of moves (possibly zero) and he’d like to make the string 𝑠 as clean as possible. He thinks for two different strings 𝑥 and 𝑦, the shorter string is cleaner, and if they are the same length, then the lexicographically smaller string is cleaner.

Now you should answer 𝑡 test cases: for the 𝑖-th test case, print the cleanest possible string that Lee can get by doing some number of moves.

Small reminder: if we have two strings 𝑥 and 𝑦 of the same length then 𝑥 is lexicographically smaller than 𝑦 if there is a position 𝑖 such that 𝑥1=𝑦1, 𝑥2=𝑦2,…, 𝑥𝑖−1=𝑦𝑖−1 and 𝑥𝑖<𝑦𝑖.

Input
The first line contains the integer 𝑡 (1≤𝑡≤104) — the number of test cases.

Next 2𝑡 lines contain test cases — one per two lines.

The first line of each test case contains the integer 𝑛 (1≤𝑛≤105) — the length of the string 𝑠.

The second line contains the binary string 𝑠. The string 𝑠 is a string of length 𝑛 which consists only of zeroes and ones.

It’s guaranteed that sum of 𝑛 over test cases doesn’t exceed 105.

Output
Print 𝑡 answers — one per test case.

The answer to the 𝑖-th test case is the cleanest string Lee can get after doing some number of moves (possibly zero).

example input:

5
10
0001111111
4
0101
8
11001101
10
1110000000
1
1

example output:

0001111111
001
01
0
1

简单概括一下:对于一个01串,每次可以删去连续的"10"中的一个0或1,让它变得最短;如果有多个最短,取字典序最小。

开始没思路,想到贪心,每次碰到“10”就怎样怎样处理,但是发现过不了样例。。耽误了好久,才开始思考问题的本质。找规律发现,对于一串数字11…00…1…0…,最后一定可以变换成只有一个数字0或1。所以当时的思路就变成了,先把开头的0过过去,然后找之后最长的1…0…1…0,变成‘0’(字典序最小)。所以当时ac的代码是这样的:

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <cmath>
#include <vector>
using namespace std;
int t,n;
int main()
{
    cin>>t;
    while(t--){
        cin>>n;
        string s;
        cin>>s;
        string res="";
        int i=0;
        while(i<s.size()&&s[i]=='0'){
            res.push_back('0');
            i++;
        }
        int flag=0;
        while(i<s.size()){
            int j=i;
            while(j<s.size()&&s[j]=='1') j++;
            if(j==s.size()){
                if(flag) res=res+"0"+s.substr(i,s.size()-i);
                else res=res+s.substr(i,s.size()-i);
                break;
            }
            else{
                while(j<s.size()&&s[j]=='0') {flag=1;j++;}
                i=j;
                if(j==s.size()){
                    res=res+"0";
                }
            }
        }
        cout<<res<<endl;
    }
    return 0;
}

但其实换个思路来讲,其实就是要把最长的1…0…1…0…变成’0’,完全可以间接找到,也就是说,从开头走过所有的0,从结尾往头走过所有的1,剩下的不就是最长的1…0…1…0…串了吗。。哎太蠢了。。所以正常的写法如下:

#include <bits/stdc++.h>
int main() {
    int t;
    std::cin >> t;
    while (t--) {
        int n;
        std::cin >> n;
        std::string s;
        std::cin >> s;
        int i = 0, j = n;
        while (i < n && s[i] == '0')
            ++i;
        while (j > 0 && s[j - 1] == '1')
            --j;
        if (i == j) {
            std::cout << s << "\n";
        } else {
            std::cout << s.substr(0, i) + '0' + s.substr(j) << "\n";
        }
    }
    return 0;
}

C题 RationalLee
Lee just became Master in Codeforces, and so, he went out to buy some gifts for his friends. He bought 𝑛 integers, now it’s time to distribute them between his friends rationally…

Lee has 𝑛 integers 𝑎1,𝑎2,…,𝑎𝑛 in his backpack and he has 𝑘 friends. Lee would like to distribute all integers in his backpack between his friends, such that the 𝑖-th friend will get exactly 𝑤𝑖 integers and each integer will be handed over to exactly one friend.

Let’s define the happiness of a friend as the sum of the maximum and the minimum integer he’ll get.

Lee would like to make his friends as happy as possible, in other words, he’d like to maximize the sum of friends’ happiness. Now he asks you to calculate the maximum sum of friends’ happiness.

Input
The first line contains one integer 𝑡 (1≤𝑡≤104) — the number of test cases.

Next 3𝑡 lines contain test cases — one per three lines.

The first line of each test case contains two integers 𝑛 and 𝑘 (1≤𝑛≤2⋅105; 1≤𝑘≤𝑛) — the number of integers Lee has and the number of Lee’s friends.

The second line of each test case contains 𝑛 integers 𝑎1,𝑎2,…,𝑎𝑛 (−109≤𝑎𝑖≤109) — the integers Lee has.

The third line contains 𝑘 integers 𝑤1,𝑤2,…,𝑤𝑘 (1≤𝑤𝑖≤𝑛; 𝑤1+𝑤2+…+𝑤𝑘=𝑛) — the number of integers Lee wants to give to each friend.

It’s guaranteed that the sum of 𝑛 over test cases is less than or equal to 2⋅105.

Output
For each test case, print a single integer — the maximum sum of happiness Lee can achieve.

example input:

3
4 2
1 13 7 17
1 3
6 2
10 10 10 10 11 11
3 3
4 4
1000000000 1000000000 1000000000 1000000000
1 1 1 1

example output

48
42
8000000000

简单概括一下:n个数,分成k个组,第i个组大小是w[i],要使得每个组最大值+最小值的和最大。(只有一个元素的组最大值最小值都是本身)。

这个题第一眼看上去也没什么思路。。但是仔细想想,要尽可能让最大的几个值都在里面出现,然后最小的值尽量都凑到一个组里去,这样每个组的最小值会变大。所以就产生一种贪心策略:排序,然后每个组放一个最大的,然后把最小的从数量最大的组开始放。但放最大的有个问题,最大的元素要优先放在只有一个元素的组,因为这样最小值也会计算到这个大的数,就赚了。严谨的证明还是比较烦的,可以去看官网。

当时想到这个策略还是挺自然的,结果第一遍写的时候写了个bug,WA了,就以为是不可贪心的了。。又想不到其他办法,卡了半天,结果换了个方式重写了一遍就过了,也算是舒服了。。

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <cmath>
#include <vector>
using namespace std;
int t,n,k;
int a[200010],w[200010];
int main()
{
    cin>>t;
    while(t--){
        cin>>n>>k;
        for(int i=0;i<n;i++) cin>>a[i];
        for(int i=0;i<k;i++) cin>>w[i];
        sort(a,a+n);
        sort(w,w+k,greater<int>());
        long long res=0;
        int aindex=n-1,windex=k-1;
        for(;windex>=0&&w[windex]==1;windex--){
            res+=2*a[aindex];
            aindex--;
        }
        for(int i=0;i<windex+1;i++){
            res+=a[aindex--];
        }
        aindex=0;
        for(int i=0;i<windex+1;i++){
            res+=a[aindex];
            aindex+=(w[i]-1);
        }
        cout<<res<<endl;
    }
    return 0;
}

D题 TediousLee
Lee tried so hard to make a good div.2 D problem to balance his recent contest, but it still doesn’t feel good at all. Lee invented it so tediously slow that he managed to develop a phobia about div.2 D problem setting instead. And now he is hiding behind the bushes…

Let’s define a Rooted Dead Bush (RDB) of level 𝑛 as a rooted tree constructed as described below.

A rooted dead bush of level 1 is a single vertex. To construct an RDB of level 𝑖 we, at first, construct an RDB of level 𝑖−1, then for each vertex 𝑢:

  • if 𝑢 has no children then we will add a single child to it;
  • if 𝑢 has one child then we will add two children to it;
  • if 𝑢 has more than one child, then we will skip it.

在这里插入图片描述
Let’s define a claw as a rooted tree with four vertices: one root vertex (called also as center) with three children. It looks like a claw:
在这里插入图片描述
Lee has a Rooted Dead Bush of level 𝑛. Initially, all vertices of his RDB are green.

In one move, he can choose a claw in his RDB, if all vertices in the claw are green and all vertices of the claw are children of its center, then he colors the claw’s vertices in yellow.

He’d like to know the maximum number of yellow vertices he can achieve. Since the answer might be very large, print it modulo 109+7.

Input
The first line contains one integer 𝑡 (1≤𝑡≤104) — the number of test cases.

Next 𝑡 lines contain test cases — one per line.

The first line of each test case contains one integer 𝑛 (1≤𝑛≤2⋅106) — the level of Lee’s RDB.

Output
For each test case, print a single integer — the maximum number of yellow vertices Lee can make modulo 109+7.

example input

7
1
2
3
4
5
100
2000000

example output

0
0
4
4
12
990998587
804665184

这题容易想到dp,因为每个节点之后的历程都是一样的。更进一步可以发现,对于level i的树,中间下面是level i-1的树,左右挂着的是level i-2的树。所以容易想到dp[i]=dp[i-1]+2*dp[i-2]。

但是还要注意,因为level i的树的根节点和三个子树的根节点又可以形成一个claw,这个claw能不能取,还要看情况。如果三个子树的根都没用于形成claw,那么就可以形成一个新claw。可以看到i=3时形成了一个新的claw,用到了根节点,i=4的根节点就是空闲的,i=5根节点也是空闲的,到了i=6,根部就又可以形成一个新claw,而且根节点就不空了。下一次形成新claw就要等到i=9。所以dp[i]=dp[i-1]+2dp[i-2]+4(i%3==0)。代码如下:

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <stack>
#include <cmath>
#include <vector>
using namespace std;
int t,n,k;
long long dp[2000010];
int main()
{
    dp[1]=0;
    dp[2]=0;
    for(int i=3;i<=2000000;i++){
        dp[i]=(2*dp[i-2]+dp[i-1]+4*(i%3==0))%(1000000007);
    }
    cin>>t;
    while(t--){
        int x;
        cin>>x;
        cout<<dp[x]<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值