牛客周赛 Round 54 (A~E)

#牛客周赛 Round 54 (A~E)

前言:
以后会定时更新很多比赛的题解  希望借此让自己坚持赛后补题  
要不然写完就结束 自己水平没有一点提高  本人很菜所以不会更新
太难的题  加油!!!

1. ​清楚姐姐的糖葫芦

题目描述 :

输出字符'o'个数

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long 
typedef pair<int, int>pii;
const int N = 1e3 +10, MOD= 1e9+7;

void solve(){
	string str;
	cin >> str;
	int res = 0;
	for(int i = 0; i < str.length(); i++){
		if(str[i] == 'o')res++;
	}	
	cout << res << endl;
	
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
   cout.tie(0);
    int t = 1;
    //cin >> t;
	while(t--) 
   	 	solve();
    return 0;
}

很简单的签到题 唯一全对的

2. 清楚姐姐买竹鼠

题目描述 :

清楚姐姐买竹鼠,a 元可以买一只竹鼠,b 元可以买三只竹鼠,问至少买 x 只竹鼠要花多少钱。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long 
typedef pair<int, int>pii;
const int N = 1e3 +10, MOD= 1e9+7;

void solve(){
	int a, b, x;
	cin >> a >> b >> x;
	int ans = 0;
    if(b < a*3){
        int t = x/3;
	   int t2 = x%3;
	   ans = t*b+ min(a*t2, b); //如果b的价格小于a*剩余鼠的数量则 可以用b元买三只鼠
    }else{
        ans = a*x;
    }
	
	cout << ans << endl;
	
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
   cout.tie(0);
    int t = 1;
    //cin >> t;
	while(t--) 
   	 	solve();
    return 0;
}

原题目这么描述的读起来有点怪 导致我就拿了90 他这个买x只鼠 可以多余x只鼠 求至少x只鼠的最小价格

3. 竹鼠饲养物语

题目描述 :

鼠鼠快速成长饲料一共分为 m 个等级,初始时全部竹鼠都是零级竹鼠,投喂一袋"鼠鼠快速成长饲料I "可以升级为一级竹鼠,继续投喂"鼠鼠快速成长饲料 II "可以升级为二级竹鼠,......。需要注意的是,你不能越级投喂,例如,向零级竹鼠投喂"鼠鼠快速成长饲料 II "没有任何效果

清楚一共有 n 袋饲料和无限多的零级竹鼠,问最多可以进行多少次有效投喂。

给定一个数组, 问其中可以连续的累加值是多少

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long 
typedef pair<int, int>pii;
const int N = 1e3 +10, MOD= 1e9+7;

void solve(){
	int n, m;
	cin >> n >> m;
	multiset<int>S;
	for(int i = 0; i < n; i++){
        int a;
		cin >> a;
		S.insert(a);
	}
	
	int ans = 0;
    int tmp = 1e9;
	for(int i = 1; i <= m; i++){
		if(S.find(i) == S.end()) break;
        tmp = min((int)S.count(i), tmp);
		ans += tmp;
	}
	cout << ans << endl;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
   cout.tie(0);
    int t = 1;
    //cin >> t;
	while(t--) 
   	 	solve();
    return 0;
}

比时 没考虑 如果前面的值的数量少于 他后面下一个值的数量 则有效的时前面较小的数量 而不是一昧着加连续的数量

没解出来的

4. 清楚姐姐跳格子

题目描述 :

从1号格子 走到n号格子, 每个格子有一个数 可以向右或向左走该格子数的因子步 问最少走几步到n
分析 :

由于每个格子上都是正整数, 所以都有因子1, 所以肯定有一种可以一直向右 每次走一个的方法 这样要走n-1步。

最优情况是是什么呢?就是当所在的格子有个因子为(n-1) 这样一部就可以到达终点。

所以在每个格子 可以走到终点的步数一定在1~n-1,

所以可以用bfs来求解此题 从1号格子开始枚举 判断其可以走的步数 到达下一个格子

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int>pii;
const int N = 1e3+ 10;

bool vis[N];//判断该节点是否已走过

//宽搜 
void bfs(int n, vector<int>&a) {
	queue<pii>q;//宽搜队列  pii第一个存步数, 第二个存到达的节点 
	q.push({0,1});//首先 把0 和 开始1号节点进队 
	while(q.size()) {
		auto tmp = q.front();//取队首元素 
		q.pop();
		
		if(tmp.second == n) { //边界条件 到达n号格子 
			cout << tmp.first;//输出次数 
			return;
		}
		
		if(vis[tmp.second]) continue;//已被访问 
		vis[tmp.second] = true;

		for(int i = 1; i< n; i++) {//枚举到达终点 在当前格子每次可以走的步数 
			if(a[tmp.second]%i) continue; //当前步数 不是此格子因子 不能走 
			
			if(i + tmp.second <= n && !vis[tmp.second + i]) { //在当前格子可以 向右走的步数
				q.push({tmp.first+1,i + tmp.second});
			}
			if(tmp.second - i >= 1 && !vis[tmp.second - i]) {//同理 向左走 
				q.push({tmp.first+1,tmp.second-i});
			}
		}
	}
}

void solve() {
	int n;
	cin >> n;
	vector<int> a(n+1,0);
	for(int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	bfs(n,a);
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	solve();
	return 0;
}

5. 清楚姐姐的布告规划

题目描述 :

在长度为n的墙上贴布告板, 有n个布告板 要求

● 第 𝑖 张布告必须要覆盖掉布告板的第 i 个位置;

● 布告不能够相互重叠,但是可以紧贴。

问至少多少张才能贴满墙

分析 :

一道典型的DP问题 0-1背包 多了点限制

每块布告板可选 可不选 选的前提是满足第i块能把墙的第i个位置覆盖 且布告板不能重叠 所以每次选第i块布告板满足第i块布告板的左端点小于等于i,且第i块的右端点大于等于i. f[i][j] = k~前i块布告板中 能覆盖面积为j (j>=i)的最少块数为k 优化为一维 每次能选第i块的条件是 j >= i and j - a[i] + 1 <= i

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int>pii;
const int N = 5e3+ 10;

void solve() {
	int n;
	cin >> n;
	vector<int> a(n+1,0);
	for(int i = 1; i<= n; i++) {
		cin >> a[i];
	}

	vector<int>dp(n+1,1e9);
	dp[0] = 0;
	for(int i = 1; i <= n; i++) { //枚举第几块布告板
		for(int j = n; j >= a[i]; j--) { //枚举墙的总面积
			if(j >= i && j-a[i] + 1 <= i) //要求第i块布告要盖住第i块位置
				dp[j] = min(dp[j], dp[j-a[i]] + 1);
		}
	}
	if(dp[n] > n) dp[n] = -1;
	cout << dp[n] << endl;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t = 1;
	cin >> t;
	while(t--)
		solve();
	return 0;
}
相关推荐
XiaoLeisj10 分钟前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
yuyanjingtao25 分钟前
CCF-GESP 等级考试 2023年9月认证C++四级真题解析
c++·青少年编程·gesp·csp-j/s·编程等级考试
Jasmine_llq29 分钟前
《 火星人 》
算法·青少年编程·c#
闻缺陷则喜何志丹40 分钟前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径
charlie1145141911 小时前
C++ STL CookBook
开发语言·c++·stl·c++20
Lenyiin1 小时前
01.02、判定是否互为字符重排
算法·leetcode
小林熬夜学编程1 小时前
【Linux网络编程】第十四弹---构建功能丰富的HTTP服务器:从状态码处理到服务函数扩展
linux·运维·服务器·c语言·网络·c++·http
倔强的石头1061 小时前
【C++指南】类和对象(九):内部类
开发语言·c++
鸽鸽程序猿1 小时前
【算法】【优选算法】宽搜(BFS)中队列的使用
算法·宽度优先·队列