GESP『202412』c++六级编程题题解

第一道:

题目描述:

在一颗拥有无限节点的二叉树上,给定一个初始节点编号s,接下来执行n次操作:

  • U,返回当前节点的父亲节点,如果没有父亲节点,则不操作.
  • L,前往当前节点的左节点.
  • R,前往当前节点的右节点.

提醒:一个节点的左节点的编号为 2 * s,右节点为 2 * s + 1.

现在执行完n次操作,询问最后s的编号是多少.

数据范围:

子任务编号 测试点占比 n s
1 20% \(\le\) 10 \(\le\) 2
2 20% \(\le 50\) $\le $10
3 60% \(\le 10^6\) \(\le 10^{12}\)

对于所有数据,保证 \(1 \le n \le 10^6\), \(1 \le s \le 10^{12}\).

解法:

观察题目n的范围,我们发现如果直接硬算,会出现计算过程爆 long long 的情况.

结合操作介绍,我们可以得出操作 'L' 或 'R' 可以和 'U' 抵消的结论,那么既然可以抵消,那么我们将可以消的先消掉,剩下的再计算就不会爆 long long 了.

\(\mathbb{The Code:}\)

#include<bits/stdc++.h>
using namespace std;
char c;
long long n,s;
stack<char> a,b;
int main(){
	cin >> n >> s;
	while(n--){
		cin >> c;
		if(c != 'U') a.push(c);
		else{
			if(!a.empty()&&(a.top() == 'L' || a.top() == 'R')) a.pop();
			else a.push(c);
		}
	}
	while(!a.empty()){b.push(a.top());a.pop();}
	while(!b.empty()){
		if(b.top() == 'U'){
			if(s % 2 == 1 && s != 1) s = (s - 1) / 2;
			else if(s % 2 == 0) s /= 2;
		}else if(b.top() == 'L') s *= 2;
		else s = s * 2 + 1;
		b.pop();
	}
	cout<<s;
	return 0;
}

第二道:

题目描述:

小杨管理着 \(m\) 辆货车,每辆货车每天需要向 A 市和 B 市运送若干次物资。小杨同时拥有 个运输站点,这些站点位于 A 市和 B 市之间。

每次运送物资时,货车从初始运输站点出发,前往 A 市或 B 市,之后返回初始运输站点。A 市、B 市和运输站点的位置可以视作数轴上的三个点,其中 A 市的坐标为 \(0\),B 市的坐标为 \(x\),运输站点的坐标为 \(p\) 且有 \(0<p<x\),货车每次去 A 市运送物资的总行驶路程为 \(2p\),去 B 市运送物资的总行驶路程为 \(2(x-p)\)

对于第 \(i\) 个运输站点,其位置为 \(p_i\) 且至多作为 \(c_i\) 辆车的初始运输站点。小杨想知道,在最优分配每辆货车的初始运输站点的情况下,所有货车每天的最短总行驶路程是多少。

数据范围:

子任务编号 测试点占比 n m \(c_i\)
1 20% 2 2 1
2 20% \(\le 10^5\) \(\le 10^5\) 1
3 60% \(\le 10^5\) \(\le 10^5\) \(\le 10^5\)

解法:

假设一辆货车需要向 A 市运送 \(a_i\) 次物资,向 B 市运送 \(b_i\) 次物资.那么它所走的距离贡献为:

\[贡献=a_i \cdot 2p + b_i \cdot 2(x-p) = 2a_ip+2b_ix - 2b_ip = 2b_ix + 2p(a_i - b_i) \]

观察式子可以发现,\(2b_ix\) 这个量可以直接算出来,那么我们如果将 \((2a_i - 2b_i)\) 称作 \(g_i\) ,那么
最后的目标就是让 \(\sum_{i = 1}^{i \le m} p \cdot g_i\) 的结果最小就可以了.

\(\mathbb{The Code:}\)

#include<bits/stdc++.h>
using namespace std;
struct node{
	int p,c;
}farm[100005];
int n,m,cnt,x,a,b,g[100005];
bool cmp(node a,node b){
	return a.p < b.p;
}
int main(){
	cin >> n >> m >> x;
	for(int i = 1;i <= n;i++) cin >> farm[i].p >> farm[i].c;
	for(int i = 1;i <= m;i++){
		cin >> a >> b;
		cnt += 2 * b * x;
		g[i] = 2 * a - 2 * b;
	}
	sort(g + 1,g + m + 1);
	sort(farm + 1,farm + n + 1,cmp);
	for(int i = 1,j = n;i <= m && g[i] <= 0;i++){
		if(!farm[j].c) j--;
		cnt += g[i] * farm[j].p;
		farm[j].c--;
	}
	for(int i = m,j = 1;i > 0 && g[i] > 0;i--){
		if(!farm[j].c) j++;
		cnt += g[i] * farm[j].p;
		farm[j].c--;
	}
	cout<<cnt;
	return 0;
}

最后也是希望各位来年打OI一帆风顺!(>_< )ヾ(^^ )

posted @ 2024-12-10 20:33  Cai_hy  阅读(282)  评论(0)    收藏  举报