牛客周赛 Round 15

文章讲述了三个编程问题:一、计算给定正整数的切割方案使其和为偶数;二、确定使所有小写字母相等所需的最少操作次数;三、在树中找到染红边权之和最大的组合,避免共享节点。使用DFS和动态规划方法解决这些算法问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A、

题目描述

游游拿到了一个正整数,她希望将它切割成两部分,使得它们的和为偶数。游游想知道有多少种合法的切割方案?
注:切割后的正整数允许出现前导零。

输入描述:

一个正整数,大小不超过10^100000

输出描述:

一个整数,代表切割的方案数。

示例1

输入

103

输出

1

说明

切割成1+03=4是合法的,但10+3=13为奇数,不符合要求。所以有1种合法方案。

 思路:两部分,其中有一部分最后一位肯定是固定的。枚举就行

#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define fp(i,a,b) for(int i=a;i<=b;++i)
#define PII pair<int,int>
const int N=1e5+10;
const int mod=1e9+7;
const double eps=1e-5;
typedef double db;
int n;
int qsm(int x,int n)
{
	int res=1;
	while(n)
	{
		if(n&1)res=res*x%mod;
		x=x*x%mod;
		n>>=1;
	} 
	return res;
}
void solve()
{
   ; 
}
string s;
int sum=0;
signed main()
{
	cin>>s;
	int sz=s.size();
	int f=s[sz-1]-'0';
	for(int i=0;i<sz-1;i++)
	{
		int x=s[i]-'0';
		if((x+f)&1){
			;
		}
		else sum++;
	}
	cout<<sum<<"\n";
	
	return 0;
} 





B、

题目描述

对于一个小写字母而言,游游可以通过一次操作把这个字母变成相邻的字母。'a'和'b'相邻,'b'和'c'相邻,以此类推。特殊的,'a'和'z'也是相邻的。可以认为,小写字母的相邻规则为一个环。

游游拿到了一个仅包含小写字母的字符串,她想知道,使得所有字母都相等至少要多少次操作?

输入描述:

 
 

一个仅包含小写字母,长度不超过100000的字符串。

输出描述:

 
 

一个整数,代表最小的操作次数。

示例1

输入

yab

输出

3

说明

 
 

第一次操作,把'y'变成'z',字符串变成了"zab"

第二次操作,把'b'变成'a',字符串变成了"zaa"

第三次操作,把'z'变成'a',字符串变成了"aaa"

 

思路:枚举要变成哪一个字符就行

#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define fp(i,a,b) for(int i=a;i<=b;++i)
#define PII pair<int,int>
const int N=1e5+10;
const int mod=1e9+7;
const double eps=1e-5;
typedef double db;
int n;
int qsm(int x,int n)
{
	int res=1;
	while(n)
	{
		if(n&1)res=res*x%mod;
		x=x*x%mod;
		n>>=1;
	} 
	return res;
}
void solve()
{
   ; 
}
string s;
int sum=0;
int mmin=1e18;
signed main()
{
	cin>>s;
	int sz=s.size();
	
	for(int i=0;i<=25;i++)
	{
		int sum=0;
		char c='a'+i;
		for(int j=0;j<sz;j++)
		{
			int f=min(abs(s[j]-c),26-abs(s[j]-c));
			sum+=f;
		}
		mmin=min(mmin,sum);
	}
	cout<<mmin<<"\n";
	
	
	return 0;
} 





 C、


题目描述

游游有一个仅由'0'、'1'、'2'组成的字符串,但其中的一些字符被替换成了'?'。游游已经不记得原串是什么样子了,但她还记得该字符串有以下性质:

1. 字符串的相邻的字符都是不相等的。

2. 字符串的所有长度为3的连续子串,代表的三进制数的数值都是偶数。

游游希望你帮忙还原该串,你能帮帮她吗?

输入描述:

一个仅由'0'、'1'、'2'和'?'组成的字符串。'?'字符代表未知字符。
字符串长度不超过1000。
对于50%的数据,'?'字符的数量不超过2个。对于其余数据则无以上限制。

输出描述:

 
 

如果没有合法的解,则说明游游记错了,请输出-1。

否则输出一个合法的字符串。有多解时输出任意即可。

示例1

输入

1?1

输出

121

说明

 
 

121作为三进制数,其数值为16,为偶数。

输出101也是合法的。

示例2

输入

0??2

输出

0202

说明

 
 

020代表的三进制数为6,202代表的三进制数为20,都是偶数。且字符串没有两个相邻字符相等。

示例3

输入

11?

输出

-1

说明

 
 

由于已经有1和1相邻且相等,所以无解。

其实size>=4的时候 就不可能有1了。应该是个找规律的题目

#include<iostream>
#include<string>
using namespace std;
bool is(string s,string t){
    if(s.size()!=t.size())return false;
    for(int i=0;i<s.size();i++)
        if(s[i]!=t[i]&&s[i]!='?')
            return false;
    return true;
}
int main(){
    string s,t="",tt="";
    cin>>s;
    
    for(int i=0;i<s.size();i++)t+=char('0'+2*(i%2)),tt+=('0'+2*((i+1)%2));
    
    
    if(is(s,"101"))
        cout<<"101"<<endl;
    else if(is(s,"121"))
        cout<<"121"<<endl;
    else if(is(s,"1"))
        cout<<"1"<<endl;
    else if(is(s,"2"))
        cout<<"2"<<endl;
    else if(is(s,"0"))
        cout<<"0"<<endl;
    else if(is(s,"12"))
        cout<<"12"<<endl;
    else if(is(s,"10"))
        cout<<"10"<<endl;
    else if(is(s,"01"))
        cout<<"01"<<endl;
    else if(is(s,"21"))
        cout<<"21"<<endl;
    else if(is(s,"02"))
        cout<<"02"<<endl;
    else if(is(s,"20"))
        cout<<"20"<<endl;
    else if(is(s,t))
        cout<<t<<endl;
    else if(is(s,tt))
        cout<<tt<<endl;
    else
        cout<<-1<<endl;
    //cout<<t<<" "<<tt<<endl;
}

D、


题目描述

游游拿到了一棵树,树的每条边有边权。

游游准备选择一些边染成红色,她希望不存在两条染红的边共用同一个点,且最终染红边的权值之和尽可能大。你能帮帮她吗?

注:所谓树,即不包含重边、自环和回路的无向连通图。

输入描述:

第一行输入一个正整数n。代表节点的数量。

接下来的n−1n-1n−1行,每行输入三个正整数u,v,w,代表点u和点v之间有一条权值为w的无向边。

1≤n≤10^5
1≤u,v≤n
1≤w≤10^9

输出描述:

一个正整数,代表最终染红的边的权值之和的最大值。

示例1

输入

5
1 2 2
2 3 5
3 4 4
3 5 3

输出

6

说明

 
 

将点1和点2、点3和点4的边染红

 

 

#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define fp(i,a,b) for(int i=a;i<=b;++i)
#define PII pair<int,int>
const int N=2e5+10;
const int mod=1e9+7;
const double eps=1e-5;
typedef double db;
int n;
int e[N],ne[N],w[N],h[N],idx;
void add(int x,int y,int z)
{
	e[idx]=y;
	ne[idx]=h[x];
    w[idx]=z;
    h[x]=idx++;
}
int dp[N][2];
void dfs(int x,int fa)
{
//	cout<<x<<" "<<fa<<"\n";
	int mmax=0;
	for(int i=h[x];~i;i=ne[i])
	{
		int j=e[i];
		if(j==fa)continue;
		dfs(j,x);
		dp[x][0]+=max(dp[j][0],dp[j][1]);
		dp[x][1]=max(dp[x][1],w[i]+dp[j][0]);
	}
//	cout<<x<<" "<<dp[x][0]<<" "<<dp[x][1]<<"\n";
}
signed main()
{
    cin>>n;
	
	memset(h,-1,sizeof h);
	
	fp(i,1,n-1)
	{
	   int a,b,c;
	   cin>>a>>b>>c;
	   add(a,b,c);
	   add(b,a,c);	
	}	
	dfs(1,-1);
	cout<<max(dp[1][0],dp[1][1]);
	return 0;
} 
//dp[fa][0] 不选与子节点的边 




 这是我最一开始的代码。

dp[x][0] 我不要x与子节点j的边 那我加上所有max(dp[j][0],dp[j][1])就行了

dp[x][1]我要x与子节点j的边+dp[j][0]

但是其他的子节点dp[j][1]我没有算。感觉得求个sum?

#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define fp(i,a,b) for(int i=a;i<=b;++i)
#define PII pair<int,int>
const int N=2e5+10;
const int mod=1e9+7;
const double eps=1e-5;
typedef double db;
int n;
int e[N],ne[N],w[N],h[N],idx;
void add(int x,int y,int z)
{
	e[idx]=y;
	ne[idx]=h[x];
    w[idx]=z;
    h[x]=idx++;
}
int dp[N][2];
void dfs(int x,int fa)
{
	for(int i=h[x];~i;i=ne[i])
	{
		int j=e[i];
		if(j==fa)continue;
		dfs(j,x);
		dp[x][0]+=max(dp[j][0],dp[j][1]);
	}
	for(int i=h[x];~i;i=ne[i])
	{
		int j=e[i];
		if(j==fa)continue;
		dp[x][1]=max(dp[x][1],dp[x][0]-max(dp[j][0],dp[j][1])+dp[j][0]+w[i]);
	}
}
signed main()
{
    cin>>n;
	
	memset(h,-1,sizeof h);
	
	fp(i,1,n-1)
	{
	   int a,b,c;
	   cin>>a>>b>>c;
	   add(a,b,c);
	   add(b,a,c);	
	}	
	dfs(1,-1);
	cout<<max(dp[1][0],dp[1][1]);
	return 0;
} 
/*
9
1 2 4
1 7 4
1 4 5
2 8 7
2 5 7
4 3 11
3 9 123
4 6 33
*/




后来的代码就是利用dp[x][0]让这个子节点j的恢复 这样就不用求sum这种了。

### 关于周赛 Round 80 的相关信息 目前并未找到具体针对周赛 Round 80 的官方题解或比赛详情文档。然而,基于以往的比赛模式和惯例[^1],可以推测出此类赛事通常包含若干算法题目,覆盖基础数据结构、动态规划、贪心策略以及图论等领域。 #### 可能涉及的内容范围 1. **签到题 (A 题)** 这类题目一般较为简单,旨在测试选手的基础编程能力。例如简单的数学计算或者字符串处理问题。 2. **中级难度题 (B 到 D 题)** 中级难度的题目往往需要一定的算法设计能力和复杂度分析技巧。比如: - 动态规划优化问题; - 贪心算法的应用场景; - 图遍历与最短路径求解; 3. **高阶挑战题 (E 或更高)** 对于更复杂的题目,则可能涉及到高级的数据结构操作(如线段树、并查集)、组合数学推导或者其他领域内的难题解决方法。 以下是根据过往经验给出的一个假设性的例子来展示如何解答类似的竞赛问题: ```python def solve_example_problem(n, m): """ 假设这是一个关于矩阵填充的问题, 给定 n 行 m 列大小的空间,按照某种规则填充值。 参数: n -- 矩阵行数 m -- 矩阵列数 返回值: result_matrix -- 完成后的二维列表形式的结果矩阵 """ # 初始化结果矩阵为全零状态 result_matrix = [[0]*m for _ in range(n)] value_to_fill = 1 direction_changes = [(0,1),(1,0),(0,-1),(-1,0)] # 方向变化顺序:右->下->左->上 current_direction_index = 0 row,col=0,0 while True: try: if not(0<=row<n and 0<=col<m): raise IndexError() if result_matrix[row][col]==0: result_matrix[row][col]=value_to_fill value_to_fill+=1 next_row,next_col=row+direction_changes[current_direction_index%len(direction_changes)][0],\ col+direction_changes[current_direction_index%len(direction_changes)][1] if any([not(0<=next_row<n), not(0<=next_col<m), bool(result_matrix[next_row][next_col])]): current_direction_index +=1 else: row,col=next_row,next_col except Exception as e: break return result_matrix if __name__ == "__main__": test_result=solve_example_problem(4,5) for line in test_result: print(line) ``` 上述代码片段展示了如何通过模拟实现一个螺旋状填充整数值至指定尺寸矩形中的过程作为示范案例之一[^4]。 ####
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值