• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
nannandbk
博客园    首页    新随笔    联系   管理    订阅  订阅
The 2022 ICPC 网络赛第一场 CDH

The 2022 ICPC Asia Regionals Online Contest (I)

C Delete the Tree

题意:想要删掉一棵树,你可以做以下两种操作:

  1. 删除:删除一个点以及和它连的边
  2. 收缩:选择一个点\(x\)它直接连有\(2\)个点\(u,v\),我们可以把\(x\)删了,在把\(u,v\)连起来

问你:最少执行删除操作多少次?

思路:要删除次数最少,那我们先尽可能的去收缩。思考一下,一棵树最终会收缩成什么样子?

我们可以把叶子节点的链一直往上收缩,直到收缩不了为止。

反过来考虑,哪些是一定需要删除操作的?只有当是一条链的情况可以收缩,那么,对于一个点,它的度数最多是\(2\),大于\(2\)的部分要删去(只保留它自己往父亲和往儿子连的两条边)。这样的话,树就可以开始收缩了,最终收缩完以后最后一定还要删\(2\)个点(不能再收缩了)。

当然不要忘记特判\(n=1\)的情况,这种情况直接输出\(1\)就ok了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+10;
int d[N];
ll ans = 0;

/*
1
6
1 2
1 3
1 4
1 5
1 6
*/
int main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		if(n==1)
		{
			cout<<1<<"\n";
			continue;
		}
		ans = 0;
		for(int i = 1;i<=n;i++)
			d[i] = 0;
		for(int i = 1;i<n;i++)
		{
			int x,y;
			cin>>x>>y;
			d[x]++,d[y]++;
		}
		// for(int i = 1;i<=n;i++)
		// 	cout<<d[i]<<" ";
		// cout<<endl;
		for(int i = 2;i<=n;i++)
		{
			ans += max(0,d[i]-2);
		}
		ans += 2;
		ans += max(d[1] - 2, 0);
		cout<<ans<<endl;
	}	

	return 0;
}

D Find the Number

题意:一个数\(x\)被认为是好的,当且仅当其二进制末尾\(0\)的个数对于\(1\)的个数。

给你\(l,r\),让你在\([l,r]\)区间内找出好数,没有就输出\(-1\)。

思路:我们分类讨论:

  1. 当\(1\)的个数大于\(0\)的个数,那么我们想要\(0\)的个数变多。如何变多?让它进位。所以我们对当前数加上一个它的\(lowbit\)
  2. 当\(1\)的个数小于\(0\)的个数,那么我们要要\(1\)的个数变多。对当前数\(+1\)。
  3. 如果一样,那就输出

注意以上操作还要保证数在\([l,r]\)之间。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+10;

int lowbit(int x)
{
	return x&(-x);
}

int main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	int t;
	cin>>t;
	while(t--)
	{
		int l,r;
		cin>>l>>r;
		bool ok = false;
		while(l<=r)
		{
			int cnt0 = __builtin_ctz(l);
			int cnt1 = __builtin_popcount(l);
			if(cnt0==cnt1)
			{
				ok = true;
				break;
			}
			if(cnt0<cnt1)
				l += lowbit(l);
			else l += 1;
 		}
		if(ok)cout<<l<<"\n";
		else cout<<-1<<"\n";
	}
	return 0;
}

H Step Debugging

题意:告诉你几个\(C--\)语法,问你调用了库函数多少次。

思路:

法一:栈模拟。

我们对字符串做以下转化:

  1. \(repeat->(\)
  2. \(librart->1+\)
  3. \(arithemtic->0+\)
  4. 数字\(->*\)数字
  5. \(for->)\)

转化完以后,我们删去没有用的\(+\)号,之后开始做栈模拟计算结果即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+10;
string s[N],t[N],a[N];
int n,m,len;
const int mod = 20220911;
int main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	while(1)
	{
		string t;
		cin>>t;
		if(t=="fin")break;
		s[++n] = t;
	}

	for(int i = 1;i<=n;i++)
	{
		if(s[i]=="repeat")t[++len]="(";
		if(s[i]=="library")t[++len] ="1",t[++len] = "+";
		if(s[i]=="arithmetic")t[++len] ="0",t[++len] = "+";
		if(isdigit(s[i][0]))t[++len] = "*",t[++len]=s[i],t[++len] = "+";
		if(s[i]=="for")t[++len] = ")";
	}

	for(int i = 1;i<=len;i++)
	{
		if(t[i]=="+")
		{
			if(i+1<=len&&t[i+1]!=")")a[++m] = t[i];
			else{
				 continue;
			}
		}
		else if(isdigit(t[i][0])&&t[i-1]==")"){
			a[++m] = "+",a[++m] = t[i];
		}
		else a[++m] = t[i];
	};
	stack<string>tmp;
	stack<int>ans;

	int i = 1;
	ll ret = 0;
	while(i<=m)
	{
		if(a[i]=="*")
		{
			ll res = ans.top()%mod;
			ans.pop();
			res = res*stoi(a[i+1])%mod;
			tmp.push(to_string(res));
			i++;
		}
		else if(a[i]!=")")
			tmp.push(a[i]);
		else
		{
			int res = 0;
			while(tmp.top()!="(")
			{
				string x = tmp.top();
				//cout<<"x = "<<x<<endl;
				if(isdigit(x[0]))
				{
					
					res += stoi(x);
				}
				tmp.pop();
			}
			if(tmp.top()=="(")
			tmp.pop();
			//cout<<"res = "<<res<<endl;
			ans.push(res);
		}
		i++;
	}
	while(!tmp.empty())
	{
		string x = tmp.top();
		if(isdigit(x[0]))
			ret += stoi(tmp.top()),ret %= mod;
		tmp.pop();
	}
	cout<<ret%mod<<endl;
	return 0;
}

法二:\(dfs\)

#include<bits/stdc++.h>
using namespace std;
const int mod=20220911;
string s;
int res;
int dfs()
{
    string s;
    int res=0;
    while(cin>>s,s!="for")
    {
        if(s=="library")
        {
            res++;
        }
        else if(s=="repeat")
        {
            res+=dfs();        
        }
    }
    int num;
    cin>>num;
    cin>>s;
    return num*res%mod;
}
int main()
{
    cin>>s;
    while(cin>>s,s!="fin")
    {
        if(s=="library")
            res++;
        else if(s=="repeat")
            res+=dfs();
    }
    cout<<res%mod<<"\n";
    return 0;
}

A 01 Sequence

posted on 2023-08-22 00:28  nannandbk  阅读(161)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3