USACO Bronze 2024 February Problem 2 Milk Exchange

Problem

Farmer John's N (1 \leq N \leq 2*10^5) cows are lined up in a circle such that for each i in 1, 2, ..., N - 1, the cow to the right of cow i is cow i + 1, and the cow to the right of cow N is cow 1. The ith cow has a bucket with integer capacity a_i (1 \leq a_i \leq 10^9) liters. All buckets are initially full.

Every minute, the cows exchange milk according to a string s_1s_2...s_N consisting solely of the characters ‘L’ and ‘R’. if the ith cow has at least 1 liter of milk, she will pass 1 liter of milk to the cow to her left if s_i = `L ’ , or to the right if s_i = `R ’. All exchanges happen simultaneously (i.e., if a cow has a full bucket but gives away a liter of milk but also receives a liter, her milk is preserved). If a cow's total milk ever ends up exceeding a_i, then the excess milk will be lost.

FJ wants to know: after M minutes (1 \leq M \leq 10 ^ 9), what is the total amount of milk left among all cows?

INPUT FORMAT (input arrives from the terminal / stdin):

The first line contains N and M.

The second line contains a string s_1s_2...s_N consisting solely of the characters ‘L’ or ‘R’, denoting the direction each cow will pass their milk in.

The third line contains integers a_1,a_2,...,a_N, the capacities of each bucket.

OUTPUT FORMAT (print output to the terminal / stdout):

Output an integer, the sum of milk among all cows after M minutes.

Note that the large size of integers involved in this problem may require the use of 64-bit integer data types (e.g., a "long long" in C/C++).

SAMPLE INPUT:

3 1
RRL
1 1 1

SAMPLE OUTPUT:

2

Cows 2 and 3 pass each other one liter of milk, so their milk is preserved. When cow 1 passes their milk to cow 2, cow 2's bucket overflows, and one liter of milk is lost after one minute.

SAMPLE INPUT:

5 20
LLLLL
3 3 2 3 3

SAMPLE OUTPUT:

14

Each cow is passing a liter of milk to the cow on the left and gaining a liter of milk from the cow on the right, so all of the milk is preserved regardless of how much time passes.

SAMPLE INPUT:

9 5
RRRLRRLLR
5 8 4 9 3 4 9 5 4

SAMPLE OUTPUT:

38

Initially, there are a total of 51 liters of milk. After 5 minutes, cows 36, and 7 will lose 5, 3, and 5 liters of milk respectively. Therefore, a total of 38 liters of milk remain.

SCORING:

  • Inputs 4-8: N,M \leq 1000
  • Inputs 9-16: No additional constraints.

Solution

算法与解法 

(讲得有可能不清楚,请谅解)

 观察题目,发现 R 倒入右边桶内,L 倒入左边桶内,那如果当序列中出现了 RL,就代表左边奶牛会给右边 1L,右边奶牛会给左边 1L,就代表这两个奶牛的瓶子一直保持着满瓶的状态,如果一旦外面有牛奶倒入,就会使瓶子满杯而产生总量损失,也只有这种情况会产生损失。外面有任何牛奶倒入就代表:左边临近的奶牛字符为 R ,后边临近的奶牛字符为 L。这就说明左/右一定会浪费牛奶,浪费牛奶数应为 min(m, a_i),因为倒牛奶最多有 m 轮,每轮只能给予一升牛奶,mL 便是最大值了,但如果奶牛已没有奶了,便无法给予。

但对于每个 RL 输入的数值不仅取决于临近的 R 与 L,也可能有一下情况:

RRRRRLLLLL

我们会发现中间有一个 RL,而左边是 4 个 R,这会引发一个奇妙的现象:最左边的 R 每轮给予下一个 R 一升,下一个 R 会给予再下一个 R 一升,引发了一个接力,直到将牛奶给予了 RL 。出现了这个“接力”现象,计算浪费牛奶数就有亿点儿困难了,我们可以发现最后一个奶牛会经过接力持续给予牛奶,当没有牛奶时,就需要倒数第二个奶牛给予牛奶;当倒数第二个奶牛没有牛奶时,就需要倒数第三个奶牛给予牛奶……以此类推。根据这个现象,我们可以找到解决方法:从 RL 处往左开始遍历,要求 R 不断开,则每一个就是 sum = min(sum + a_i, m)。其实就是将附近的 R 奶牛所持有的牛奶数累加,最大值不超过 m,找出一共可以给予 RL 多少升牛奶(也就是损失了多少牛奶)。L 与以上做法同理,只不过换了一个遍历方向。

综上所述,我们需要找到每个 RL,被找到给 RL 提供牛奶的奶牛,计算损失数,把所有损失数从总牛奶数减去,即为答案。

特别要提醒的是:第一只奶牛与第 n 只奶牛是连起来的,在遍历和寻找 RL 请注意这一点。

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 1;
int n, m, res, a[N];
char c[N];
signed main(){
	scanf("%lld%lld%s", &n, &m, c);
	for(int i = 1;i <= n; i++){
		scanf("%lld", &a[i]);
		res += a[i];						//计算总牛奶值 
	}
	if(c[0] == 'L' && c[n - 1] == 'R')		//第一个与第 n 个形成 RL
		c[0] = ' ', c[n - 1] = ' ';
	for(int i = 1;i < n; i++)
		if(c[i - 1] == 'R' && c[i] == 'L')	//i-1 与 i 形成 RL
			c[i - 1] = ' ', c[i] = ' ';		//用空格代替,以记录 
	for(int i = 0;i < n; i++){
		int suma = 0, sumb = 0;				//suma 记录左边相连的奶牛给予牛奶的数量,sumb 则是记录右边的 
		int l = i - 1;
		if(l < 0)
			l = n - 1;
		if(c[l] != ' ' || c[i] != ' ')
			continue ;
		bool flag = false;
		for(int j = l - 1;j >= 0 && !flag; j--){
			if(c[j] == 'R')					//是否相连 
				suma = min(suma + a[j + 1], m);
			else
				flag = true;
		}
		if(!flag){							//如果持续相连直到第一个,那就从第 n 个往前检查是否还有相连 
			for(int j = n - 1;j >= 0 && !flag; j--){
				if(c[j] == 'R')
					suma = min(suma + a[j + 1], m);
				else
					flag = true;
			}
		}
		flag = false;						//以下同 suma 
		for(int j = i + 1;j < n && !flag; j++){
			if(c[j] == 'L')
				sumb = min(sumb + a[j + 1], m);
			else
				flag = true;
		}
		if(!flag){
			for(int j = 0;j < n && !flag; j++){
				if(c[j] == 'L')
					sumb = min(sumb + a[j + 1], m);
				else
					flag = true;
			}
		}
		res -= suma + sumb;					//从总牛奶数减去此 RL 损失数
	}
	printf("%lld", res);
	return 0;
}

文章创作了 \infty 小时,点个赞再走 ~

相关推荐

  1. 2024/2/2

    2024-02-20 23:10:02       51 阅读
  2. 作业2024/2/2

    2024-02-20 23:10:02       53 阅读
  3. 2024.2.1

    2024-02-20 23:10:02       53 阅读
  4. <span style='color:red;'>2024</span>.<span style='color:red;'>2</span>.3

    2024.2.3

    2024-02-20 23:10:02      44 阅读
  5. 作业2024/2/6

    2024-02-20 23:10:02       44 阅读
  6. 2024/2/5

    2024-02-20 23:10:02       46 阅读
  7. 2024/2/6

    2024-02-20 23:10:02       49 阅读
  8. 2024/2/6

    2024-02-20 23:10:02       51 阅读
  9. 2024/2/7

    2024-02-20 23:10:02       53 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-20 23:10:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-20 23:10:02       106 阅读
  3. 在Django里面运行非项目文件

    2024-02-20 23:10:02       87 阅读
  4. Python语言-面向对象

    2024-02-20 23:10:02       96 阅读

热门阅读

  1. 15个学习Go语言的网站推荐

    2024-02-20 23:10:02       44 阅读
  2. 最优字符串分隔符:零宽度空格和字符

    2024-02-20 23:10:02       47 阅读
  3. 计算机网络第三章问答题

    2024-02-20 23:10:02       46 阅读
  4. 设计模式7大原则+类图关系

    2024-02-20 23:10:02       48 阅读
  5. 在 SQL Server 中编写函数以获取年加周的字符串

    2024-02-20 23:10:02       44 阅读
  6. 学会自幂数

    2024-02-20 23:10:02       55 阅读
  7. Leetcode 367. Valid Perfect Square

    2024-02-20 23:10:02       45 阅读