首页 > 编程语言 >第十届蓝桥杯c++b组国赛题解(还在持续更新中...)

第十届蓝桥杯c++b组国赛题解(还在持续更新中...)

时间:2023-06-03 20:22:05浏览次数:60  
标签:... int 题解 s1 long 蓝桥 s2 include dp

试题A:平方序列

image
解题思路:

直接枚举一遍x的取值,然后按照题目给定的式子算出y,每次取x+y的最小值即可
答案为7020

代码实现:

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define int long long
const int N=1e4+5;
signed main(){
	//记录答案 
	int res=0x3f3f3f3f;
	//循环枚举x 
	for(int i=2020;i<=N;i++){
		//计算y*y; 
		int t=2*i*i-2019*2019;
		//判断该值是否是完全平方数 
		int j=sqrt(t);
		//如果是表示存在y,使得y*y满足题目的等差数列
		//每次记录x+y的最小值 
		if(j*j==t)res=min(j+i,res);
	}
	cout<<res<<endl;
	return 0;
}

试题B:质数拆分

image
解题思路:

先将1~2019中的所有质数筛选出来,将每个质数视为一个价值为自身值的物品,然后直接利用背包问题求解,即从前i个物品中选,且当前价值为j的所有选法数。
考虑状态转移方程
1.不选当前物品:dp[i][j]+=dp[i-1][j];
2.选当前物品:dp[i][j]+=dp[i-1][j-w[i]];
答案为55965365465060

代码实现:
二维未优化版本

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define int long long
const int N=2500;
int prime[N],vis[N],cnt;
//dp[i][j]表示从前i个物品中选且当前值为j的选法数 
int dp[N][N];
void init(int n){
	for(int i=2;i<=n;i++){
		if(!vis[i])prime[++cnt]=i;
		for(int j=1;prime[j]*i<=n;j++){
			vis[prime[j]*i]=1;
			if(i%prime[j]==0)break;
		}
	}
}
signed main(){
	//利用线性筛将1~2019中的质数都筛选出来存储到prime数组中
	//由于背包问题下标习惯从1开始,所以prime数组存储的质数下标从1开始 
	init(2019);
	//如果价值为0,则选法只有不选这一种 
	for(int i=0;i<=cnt;i++)dp[i][0]=1; 
	for(int i=1;i<=cnt;i++){
		for(int j=1;j<=2019;j++){
			//不选当前物品 
			dp[i][j]+=dp[i-1][j];
			//选当前物品 
			if(j>=prime[i])dp[i][j]+=dp[i-1][j-prime[i]];
		}
	}
	cout<<dp[cnt][2019]<<endl;
	return 0;
}

一维优化版本

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define int long long
const int N=2500;
int prime[N],vis[N],cnt; 
int dp[N];
void init(int n){
	for(int i=2;i<=n;i++){
		if(!vis[i])prime[++cnt]=i;
		for(int j=1;prime[j]*i<=n;j++){
			vis[prime[j]*i]=1;
			if(i%prime[j]==0)break;
		}
	}
}
signed main(){
	//利用线性筛将1~2019中的质数都筛选出来存储到prime数组中
	//由于背包问题下标习惯从1开始,所以prime数组存储的质数下标从1开始 
	init(2019);
	dp[0]=1;
	for(int i=1;i<=cnt;i++){
		for(int j=2019;j>=0;j--){
			if(j>=prime[i])dp[j]+=dp[j-prime[i]];
		}
	}
	cout<<dp[2019]<<endl;
	return 0;
}

试题C:拼接

image
解题思路:

代码实现:

试题D:求值

image
解题思路:

直接for循环遍历,每次求当前数的约数个数,如果当前约数个数为100,则输出结果并退出循环
约数个数求法:
image
答案为45360

代码实现:

#include<iostream>
#include<unordered_map>
using namespace std;
#define int long long
unordered_map<int,int>mp;
void divide(int x){
	//从前往后遍历,求解x的质因子及其次幂 
    for(int i=2;i<=x/i;i++){
        //如果当前数能够被x整除,说明i是x的一个因子 
		//求解i的次幂 
		while(x%i==0){
            x/=i;
            mp[i]++;
        }
    }
    //别忘了最后为除尽的数 
    if(x>1)mp[x]++;
}
signed main(){
	//for循环遍历一遍,求每个数的约数个数 
    for(int i=100;i;i++){
    	mp.clear();
    	int res=1;
    	//分解质因数 
    	divide(i);
    	//根据公式求解当前数的约数个数 
    	for(auto t:mp)res=res*(t.second+1);
		//如果当前数的约数个数为100,则输出当前答案并返回 
		if(res==100){
			cout<<i<<endl;
			break;
		}
	}
    return 0;
}

试题E:路径计数

image
解题思路:

从起点(0,0)开始dfs,dfs每次可以往上、下、左、右四个方向走,每次走过的点都要标记一下,不能重复走,如果步数大于12,则直接return,如果回到了起点(0,0)且当前步数大于2则答案加1
答案为206
\(\textcolor{red}{注意步数必须大于2,由于起点是没有被标记的,那么会存在从起点出发立即回到起点的情况,其步数等于2,但是这是不合法的走法}\)

代码实现:

#include<iostream>
#include<unordered_map>
using namespace std;
#define int long long
const int N=10;
int res,vis[N][N];
//模拟上下左右四个方向 
int d1[4]={0,0,1,-1}; 
int d2[4]={1,-1,0,0};
//x,y表示当前所在位置,cnt表示当前的步数 
void dfs(int x,int y,int cnt){
	//如果步数大于题目要求的12,直接return 
	if(cnt>12)return;
	//如果步数大于2而且当前在起点(0,0),则答案加1并返回 
	if(cnt>2&&x==0&&y==0){
		res++;
		return;
	}
	//往上下左右四个方向递归 
	for(int i=0;i<4;i++){
		int x1=x+d1[i];
		int y1=y+d2[i];
		//如果被标记了或者越界了,则不能走 
		if(x1<0||x1>5||y1<0||y1>5||vis[x1][y1])continue;
		//标记当前位置被走过了 
		vis[x1][y1]=1;
		//递归,步数加1 
		dfs(x1,y1,cnt+1);
		//恢复现场 
		vis[x1][y1]=0;
	}
}
signed main(){
	dfs(0,0,0); 
	cout<<res<<endl;
    return 0;
}

试题F:最优包含

image
解题思路:

考虑状态转移方程:
dp[i][j]指s1以第i位结尾,s2以第j位结尾的最少修改次数
当s1[i]==s2[j]时,则可以不修改s1,所以dp[i][j]=dp[i-1][j-1]
当s1[i]!=s2[j]时,有两种情况:
1)不修改s1[i],让s1的前i-1个字符与s2前j个字符匹配,此时修改次数不变(因为是包含关系),即dp[i][j]=dp[i-1][j]
2)修改s1[i],让s1的前i-1个字符与s2前j-1个字符相等,此时修改次数加一,即dp[i][j]=dp[i-1][j-1]+1

代码实现:

#include<iostream>
#include<cstring>
using namespace std;
#define int long long
const int N=1005;
//dp[i][j]指s1以第i位结尾,s2以第j位结尾的最少修改次数
int dp[N][N]; 
signed main(){
	//因为求最小值,所以初始化为最大值 
	memset(dp,0x3f,sizeof dp);
	string s1,s2;
	cin>>s1>>s2;
	//一般dp下标从1开始,所以让字符串前补个空格 
	s1=" "+s1;
	s2=" "+s2;
	//边界条件:当s2长度为0时,不需要修改,故为0 
	for(int i=0;i<=s1.size();i++)dp[i][0]=0;
	for(int i=1;i<=s1.size();i++){
		for(int j=1;j<=s2.size();j++){
			//如果s1[i]==s2[j],则s1的第i位和s2的第j位不需要考虑
			//故dp[i][j]=dp[i-1][j-1] 
			if(s1[i]==s2[j])dp[i][j]=min(dp[i][j],dp[i-1][j-1]);
			else{
				//如果s1[i]!=s2[j],存在2种情况,可以修改,也可以不修改
				//如果修改,则dp[i][j]=d[i-1][j-1]+1;
				//如果不修改,则dp[i][j]=dp[i-1][j]
				//取二者最小值 
				dp[i][j]=min(dp[i][j],min(dp[i-1][j-1]+1,dp[i-1][j]));
			}
		}
	}
	cout<<dp[s1.size()][s2.size()]<<endl;
    return 0;
}

标签:...,int,题解,s1,long,蓝桥,s2,include,dp
From: https://www.cnblogs.com/hxss/p/17454112.html

相关文章

  • ABC215E 题解
    前言题目传送门!更好的阅读体验?萌萌DP题。思路题目就是在说从\(a\)里面按顺序掏出来一些字母,使得相同的字母都是相邻的(比如AABBBBCD可行,AAABBCAA不行)。看起来很不可做,突破口在于\(\text{A}\sim\text{J}\)一共只有\(10\)个字母,考虑状压。设\(dp_{i,s}\)表示......
  • 道路翻修题解
    \(\mathcal{Description}\)给定一张无向图,为每条边定向,定义每个点的价值为出度与入度之差的绝对值,求最大价值和。对于\(40\%\)的数据,\(1\leqn,m\leq20\)。对于\(70\%\)的数据,\(1\leqn\leq17\)。对于\(90\%\)的数据,\(1\leqn\leq22\)。对于所有数据,\(1\leqn\leq25\)......
  • CF1808E3 题解
    题意传送门求有多少包含\(n\)位数码的\(k\)进制数,满足存在一位数等于其他\(n-1\)位数的总和模\(k\)。\(1\len\le10^{18},1\lek\le2000\)。题解简单的组合数学都不会了……蔬菜越来越多,我该怎么办?条件等价于存在某一位\(x\),满足\(2x\equivs\pmodk\)。容易想到......
  • 蓝桥WP
    CyberChef可以看出是先将flagbase64加密一下然后ROT13加密先手动爆破出ROT13得ZmxhZ3tkY2I3N2FiYy02NDQ1LTQ4NDAtYmJjYS01MjUyZjYwNzM1ZTd9然后base64解密得flagflag{dcb77abc-6445-4840-bbca-5252f60735e7}XORIDA64打开,一眼小端序和循环异或key为SEcRET7,写个脚本fl......
  • P1545 [USACO04DEC] Dividing the Path G 题解
    丢一发好理解又好写的线段树优化dp。题目传送门简要题意给定一个长为\(l\)的线段,求出尽量少的不相交区间覆盖整段线段,要求题目给的所有子区间只被\(1\)个区间覆盖。分析显然题目给的子区间\([s,e]\)中只有\(s\)和\(e\)端点能作为线段端点,所以我们应该给\([s+1,......
  • 【蓝桥杯集训·每日一题】AcWing 1079. 叶子的颜色
    写在前面本人CSDN博客主页:这里一、题目1、原题链接1079.叶子的颜色2、题目描述给一棵有m个节点的无根树,你可以选择一个度数大于1的节点作为根,然后给一些节点(根、内部节点、叶子均可)着以黑色或白色。你的着色方案应保证根节点到各叶子节点的简单路径上都至少包含一个有色节点,哪......
  • 【Pytorch】ValueError: not enough values to unpack (expected 2, got 1)问题解决
    在运行开源项目时出现了这个问题,网上很多说删回车或者都改成英文符号,但是我都试了,没用后来自己摸索出的方法是:先更改数据集的格式,之前分隔符是\t,把数据集中的分隔符改成空格,再把语句中的\t也换成空格,然后就不会报错了。改前:改后:......
  • python pip安装库时遇到fatal error的问题解决
    当时的图片没有留,写点东西做备忘吧。一开始尝试pipinstallxx库,cmd提示pip不是批处理文件或命令,解决方法:去属性的高级设置里,在用户变量的Path里增加pip所在的路径,如果不知道pip在哪里,就在cmd里输入wherepip查询,查不到就在文件管理里用查询。解决这个问题后,再尝试安装,错误提示......
  • 2016第七届蓝桥杯国赛决赛c/c++本科B组试题总结及解题答案
    未完待更新........1.一步之遥从昏迷中醒来,小明发现自己被关在X星球的废矿车里。矿车停在平直的废弃的轨道上。他的面前是两个按钮,分别写着“F”和“B”。小明突然记起来,这两个按钮可以控制矿车在轨道上前进和后退。按F,会前进97米。按B会后退127米。 透过昏暗的灯光,小明看......
  • 杂项题解
    JOISC2017_JAbduction2由于权值较高的路不会被权值较低的路线影响,所以首先考虑将\(h+w\)条边按照权值降序排序,再考虑应该的最优决策方案。注意到每一条路都横跨原始的矩形,这样以出发点为中心向上下左右发散就会有4条边构成一个小矩形。考虑维护这个矩形每条边的最大路径......