Codeforces Global Round 16

A题

  • 思路

前面全填零

  • 代码
void solve()
{
	ll n,s;cin >> n >> s;
	// cout<<1<<endl;
	ll m = (n+1) / 2;
	// cout<<2<<endl;
	if(n==1){
		cout<<s<<endl;return;
	}
	ll ans = (s) / (n-m+1);
	// cout<<3<<endl;
	ans = max (0*1ll,ans);
	cout << ans << endl;
}

B题

  • 思路

连续 0 的串会产生贡献 1

  • 代码

void solve()
{
	string s;cin>>s;
	int cnt=0;
	for(int i = 0 ;i < s.size() ;i ++){
		if(s[i]=='0'){
			cnt++;
			while(s[i] == '0') 
				i ++;
		}
	}
	cout<<min(2,cnt)<<endl;
}

C题

  • 思路

仔细分析一下,就那么几种情况;用一个变量 case1,case0,记录前面是否存在
0 1
0 1
这样的情况。
因为
1
1这样的情况肯定是最后要尽量找 0 | 0.
0
0这样的情况肯定是最后要尽量找 1 | 1。因为这样的贡献才会更大。
还有一些细节要处理

  • 代码
void solve()
{
	int n;cin>>n;
	string s1,s2;
	cin>>s1>>s2;
	int cnt = 0;
	int case1 = 0,case0 = 0;
	for(int i = 0;i < n;i ++){
		if(s1[i] != s2[i]){
			cnt+=case0;//归零之前要确定前面是否存在
			0
			0 这样的情况。
			cnt+=2;case1 = case0 = 0;
		}
		else {
			if(s1[i] == '0'){
				if(case0 == 1){
					cnt +=1;continue;
				}
				if(case1 == 1){
					cnt +=2;
					case0 = case1 = 0;continue;
				}
				if(case0 == 0&&case1 == 0){
					case0 = 1;
				}
			}
			if( s1[i] == '1'){
				if(case0 == 1){
					cnt +=2; case0 = case1 = 0;
					continue;
				}
				if(case0 == 0 && case1 == 0){
					case1 = 1;
				}
			}
		}
	}
	cnt+=case0;
	cout<<cnt<<endl;
}

D题

  • 思路

因为要求视力低的位置靠前,所以无论哪个版本,都是已经确定了最终位置。
现在要考虑的是,如何处理视力相等的,尽量产生的贡献值最少。贪心地想,肯定是首先出现的要安排位置靠后,这样才不会对同等视力的产生贡献;其次,对于多个数值的,例如
4 2
50 50 50 50 3 50 50 50。
肯定是前面的 50 先填了,然后 3 再填上。

  • 代码
void solve_test()
{
    int n,m;cin>>n>>m;
    vector<pair<int,int> >a(n*m);
    for(int i=0;i<n*m;i++){
        cin>>a[i].first;
        a[i].second=i;
    }
    sort(a.begin(),a.end());
    for(int i=0;i<n*m;i++){
        a[i].second=-a[i].second;
    }
    int res=0;
    for(int i=0;i<n;i++){
        sort(a.begin()+m*i,a.begin()+(m*i+m));
        for(int j=0;j<m;j++){
            for(int k=0;k<j;k++){
                if(a[i*m+k].second>a[i*m+j].second) res++;
            }
        }
    }
    cout<<res<<endl;
}

E题

  • 思路
    因为贪心的讲,把 bud 挂在 leaf 上就会减少 一个,所以肯定是一个 bud 挂在另一个 bud 的leaf 下面。假设有 k 个 bud ,那么就会有 n-k-1个 leaf 。会挂 k-1 个 bud,也就减少了 k-1 个 leaf。那么答案就是 n-k2-1。注意特判 root。如果 root 不是 bud ,那 答案就是 n-2k-1。否则答案就是 n-2*k。
  • 代码
#include<bits/stdc++.h>

using namespace std;

vector<vector<int> > g;
vector<int> type;

void dfs(int v,int p)
{
    bool leaves = false;
    for(auto to : g[v]){
        if(to == p) continue;
        dfs(to,v);
        if(type[to] == 1) leaves = true;
    }
    if(v != p){
        if(!leaves) type[v] = 1;
        else type[v] = 2;
    }
}

int main()
{
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        g.assign(n,vector<int>());
        type.assign(n,-1);
        for(int i=0;i<n-1;i++){
            int x,y;
            cin>>x>>y;--x;--y;
            g[x].push_back(y);
            g[y].push_back(x);
        }
        type[0]=0;
        dfs(0,0);
        bool root_leaf = false;
        for(auto v:g[0]){
            if(type[v] == 1){
                root_leaf = true;
            }
        }
        int k=0;
        for(int i=0;i<n;i++){
            k+=(type[i]==2);
        }
        cout<<n-2*k-root_leaf<<endl;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯狂的码泰君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值