牛客周赛 Round 54 (A~E)

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

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

1. ​清楚姐姐的糖葫芦

题目描述 :
输出字符‘o’个数

#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 只竹鼠要花多少钱。

#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 袋饲料和无限多的零级竹鼠,问最多可以进行多少次有效投喂。

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

#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号格子开始枚举 判断其可以走的步数 到达下一个格子

#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
i满足的左右边界

#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;
}
牛客 a卷2022年第四季度的华为题目中,要求考生设计一种高效的数据结构,能够支持以下几种操作: 1. 添加一个元素 2. 删除一个元素 3. 查找是否存在某个元素 4. 返回元素的总数 该数据结构要求满足空间复杂度较小、时间复杂度较低、能够快速地进行查找和修改等多种操作。 想要编写这样一种数据结构,我们可以参考许多已有的经典算法与数据结构,如二叉树、哈希表、红黑树等,通过综合利用它们的优点来实现这个问题的解决。 例如,我们可以通过哈希表来存储所有元素的值,并在每个哈希链表的元素中再使用红黑树来进行排序与查找。这样,我们既能够轻松地进行元素的添加和删除操作,也能够在查找较大数据范围和数量时保持较高的速度与效率。同时,由于使用了多个数据结构来协同完成这个问题,我们也能够在空间复杂度上适度地进行优化。 当然,在具体设计这个数据结构的过程中,我们还需要考虑一些实践中的细节问题,例如如何避免哈希冲突、如何处理数据丢失与被删除元素所占用的空间等问题,这都需要相应的算法与流程来进行处理。 总体来看,设计这种支持多种操作的高效数据结构,需要我们具备丰富的算法知识和编程实践能力,同时需要我们在具体处理问题时能够将多种算法和数据结构进行有效地结合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值