2024暑假集训第二次考试

10062. Majority Opinion

思路分析

        这道题就是一道思维题,这种题需要刻意练习,形成一定的思维模式用之前学过算法的原理去思考问题,而不是一味考验某一种算法的应用。

        这道题就需要思考的是什么情况可以让这个奶牛爱吃同一种干草,分析如果大于半的奶牛喜欢吃同一种干草那么这些奶牛就会都喜欢吃这种干草,那么先从规模最小的3个奶牛思考问题(因为大于一般的奶牛数量最少也要三头)那么观察规律可得,bba,或者是bab,或者是abb三种情况可以满足条件,再分析一下,bba,和abb都是有两头喜欢吃一种干草的奶牛并列,而bab是两头喜欢吃一种干草的奶牛中间隔了一头奶牛,所以规律就推出来了,因为接下来不管是几头奶牛绝对会被同化。

AC代码

#include<iostream>
#include<cstring>
#include<vector>
#include<cmath> 
#include<algorithm>
using namespace std;

const int N = 1e6+10;
const int M = 1e2;
int a[N],s[N];
vector<int> g;

int main(){
	int t; cin >> t;
	while(t--){
		int n; cin >> n;
		for(int i = 1; i <= n; i++){
			scanf("%d",&a[i]);
			//abb或bba型 
			if((a[i] == a[i+1] || a[i] == a[i-1]) && !s[a[i]]){
				g.push_back(a[i]);
				s[a[i]] = 1;
			}
			//bab型 
			if((a[i] == a[i+2] || a[i] == a[i-2]) && !s[a[i]]){
				g.push_back(a[i]);
				s[a[i]] = 1;
			}
		} 
		sort(g.begin(),g.end());
		if(g.empty()) cout << -1 << endl;
		else{
			for(int i = 0; i < g.size(); i++){
				cout << g[i] << " ";
			}
			cout << endl; 
		}
		memset(s,0,sizeof(s));
		memset(a,0,sizeof(a));
		g.clear();
	} 
	return 0;
} 

10063. Cannonball

思路分析

        这本来就是一道简单的模拟题,但是你如果纯模拟就会超时,所以需要一点优化,注意题目中的一句话,如果 Bessie 弹跳无限长的时间或直到她离开数轴,她会击破多少个炮击目标,所以有可能他会在两个跳板之间来回跳,所以我们需要判断一下如果他跳的次数超过3*1e5(因为跳板就1e5那么长,所以你跳同一个地方3次多肯定是反复横跳了,直接结束)

代码

#include<iostream>
using namespace std;

const int N = 1e5+10;
typedef pair<int,int> PII;
int n,s,cnt = 0,st[N];
PII a[N];

int main(){
	cin >> n >> s;
	for(int i = 1; i <= n; i++){
		cin >> a[i].first >> a[i].second;
	}
	int v = 1,ff = 1,t = 0; //t是看跳跃次数的 
	while(s <= n && s > 0 && t < 1e5*5){
		t++;
		if(a[s].first == 0){
			if(ff < 0) ff = 1;
			else ff = -1;
			v += a[s].second;
		}
		else{
			if(!st[s]){
				if(a[s].second <= v){
					cnt++;
					st[s] = 1;
				}
			}
		}
		s += v*ff;
	}
	cout << cnt << endl;
	return 0;
}

10064. Balancing Bacteria

思路分析

        题目用到的算法是二分,两次二分,但是本质上是一道思维题,他每次喷洒药水是一个等差数列,所以就只需要把他进行二次差分操作,统计出来不为零的的绝对值的草相加,就为喷洒草药的次数。可能有点难理解,可以看一下luogu上这道题的题解:登录 - Luogu Spilopelia

代码

#include <iostream>
#include <cmath>
using namespace std;

const int N = 1e6;
long long n,a[N],s[N],s2[N],ans;
//别忘了long long
int main(){
    cin>>n;
    for(int i = 1;i<=n;i++){
        cin>>a[i];
        s[i]=a[i]-a[i-1];
        s2[i]=s[i]-s[i-1];
        ans+=abs(s2[i]);
    }
    cout<<ans;
}

10065. Cow Party S

思路分析

         第四题是一个图论的模版题目,所以我们只需要背板子即可。(当时没做出来,板子掌握不熟练,上午讲下午就考我也真服了)Dijkstra最短路径算法,但是需要注意的,在求每个农场到x的距离并不等于x到每个农场的距离(题目让求来回),因为这是有向图,所以就需要反向建边(比如是a-b的边我们就建b-a的边)然后再跑一遍Dijkstra算法即可

代码

#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

const int N = 1e5+10;
typedef pair<int,int> PII;
struct Node{
	int a,b,c;
} tmp[N];
int h[N],e[N],ne[N],dist[N],s[N],w[N],idx,n,m,sum[N];

void add(int a, int b,int c){
	e[idx] = b;
	w[idx] = c;
	ne[idx] = h[a];
	h[a] = idx;
	idx++;
}

void dijkstra(int st){
	memset(dist,0x3f,sizeof dist);
	memset(s,0,sizeof s);
	priority_queue<PII,vector<PII>,greater<PII> > q;
	dist[st] = 0;
	q.push({dist[st],st});
	while(!q.empty()){
		auto t = q.top();
		q.pop();
		int k = t.second,dis = t.first;
		if(s[k]) continue;
		s[k] = 1;
		for(int i = h[k]; i != -1; i = ne[i]){
			int j = e[i];
			if(dis+w[i] < dist[j]){
				dist[j] = dis+w[i];
				q.push({dist[j],j});		
			}
		}
	}
	for(int i = 1; i <= n; i++){
		sum[i] += dist[i];
	}
}

int main(){
	memset(h,-1,sizeof h);
	int x; 
	cin >> n >> m >> x;
	for(int i = 1; i <= m; i++){
		int a,b,c; cin >> a >> b >> c;
		add(a,b,c);
		tmp[i] = {a,b,c};		
	}
	dijkstra(x);
	memset(h,-1,sizeof h);
	idx = 0;
	for(int i = 1; i <= m; i++){
		add(tmp[i].b,tmp[i].a,tmp[i].c);		
	}
	dijkstra(x);
	int mx = -1e9;
	for(int i = 1; i <= n; i++){
		mx = max(sum[i],mx);
	}
	cout << mx << endl;
	return 0;
}

总结

        这是暑假集训第二次考试总体成绩不理想,但是要继续加油,出现的问题主要是算法模版掌握不牢,所以要理解性记忆算法模版,以及思维题做的不好,要多练习思维题,提高逻辑思维

每一次的努力,都是为了更好的未来。不要害怕失败,因为失败只是通往成功的必经之路。坚持学习,坚持成长,未来就在你的手中。

  • 13
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值