AcWing 4118. 狗和猫 大模拟 c++和Java实现

18 篇文章 0 订阅
17 篇文章 0 订阅

题目

你在动物收容所工作,负责喂养动物。

你一共准备了 D 份狗粮和 C 份猫粮。

一共有 N 只动物排队等候用餐,有的是狗,有的是猫。

当然,也有可能全都是狗或者全都是猫。

我们可以用一个长度为 N 的由大写字母 C 和 D 组成的字符串 S 来表示队列中猫狗的顺序。

如果队列中第 i 只动物是猫,则第 i 个字符为 C。

如果队列中第 i 只动物是狗,则第 i 个字符为 D。

动物们严格按照排队顺序依次进食。

每只狗吃一份狗粮,每只猫吃一份猫粮。

此外,你还有额外的猫粮。

每当一条狗吃完一份狗粮,你就会为猫多提供 M 份猫粮。

每只动物都只会在排在其前面的所有动物都进食完毕后,才肯进食。

这也就意味着,当轮到某只动物进食,但是却没有相应的食物时,它和排在它后面的所有动物都会因此无法进食。

请问,在这种情况下,队列中的所有狗能否都得到喂食。

输入格式
第一行包含整数 T,表示共有 T 组测试数据。

每组数据第一行包含四个整数 N,D,C,M。

第二行包含一个长度为 N 的由大写字母 C 和 D 组成的字符串 S。

输出格式
每组数据输出一个结果,每个结果占一行。

结果表示为 Case #x: y,其中 x 为组别编号(从 1 开始),如果所有狗都能得到喂食,则 y 为 YES,否则 y 为 NO

数据范围
1 ≤ T ≤ 100,
1 ≤ N ≤ 104,
0 ≤ D,C ≤ 106,
0 ≤ M ≤ 106

输入样例1:

3
6 10 4 0
CCDCDD
4 1 2 0
CCCC
4 2 1 0
DCCD

输出样例1:

Case #1: YES
Case #2: YES
Case #3: NO

样例1解释
在 Case 1 中,一共有 10 份狗粮和 4 份猫粮。

  1. 前两只动物是猫,喂食它们后,还剩下 2 份猫粮。
  2. 接下来是一只狗,喂食它后,还剩下 9 份狗粮。
  3. 然后是一只猫,喂食它后,还剩下 1 份猫粮。
  4. 最后是两只狗,喂食它们后,还剩下 7 份狗粮。

所有狗都被喂食。

在 Case 2 中,没有狗,因此,所有狗(0 只)都被喂食了。

在 Case 3 中,第二只狗前面的猫得不到喂食,所有第二只狗也没法得到喂食。

`输入样例2:

2
12 4 2 2
CDCCCDCCDCDC
8 2 1 3
DCCCCCDC

输出样例2:

Case #1: YES
Case #2: NO

样例2解释
在 Case 1 中,每只狗喂食完毕后,都会额外得到两份猫粮。

  1. 首先是一只猫,喂食它后,还剩下 1 份猫粮。
  2. 接下来是一只狗,喂食它后,还剩下 3 份狗粮和 3 份猫粮。
  3. 接下来是三只猫,喂食它们后,还剩下 3 份狗粮和 0 份猫粮。
  4. 接下来是一只狗,喂食它后,还剩下 2 份狗粮和 2 份猫粮。
  5. 接下来是两只猫,喂食它们后,还剩下 2 份狗粮和 0 份猫粮。
  6. 接下来是一只狗,喂食它后,还剩下 1 份狗粮和 2 份猫粮。
  7. 接下来是一只猫,喂食它后,还剩下 1 份狗粮和 1 份猫粮。
  8. 接下来是最后一只狗,喂食它后,还剩下 0 份狗粮和 3 份猫粮。

所有狗都被喂食。

在 Case 2 中,第二只狗前面的猫得不到喂食,所有第二只狗也没法得到喂食。

解题思路

该题最多有 100 组数据,每组数据最多有 104 只动物,所以暴力解题也仅需遍历 106 次,时间复杂度允许,所以可以直接选择模拟。

注意:

  1. 每成功喂一条狗,猫粮会增加 m;
  2. 由于猫粮的总数会增加,所以猫粮的总数会超出 int 的范围,需要使用 long;
  3. 只需要判断狗能否喂完即可,不用关心猫的状态;
  4. 如果喂到当前狗没有了狗粮,说明狗不能喂完;
  5. 如果当前猫没有了猫粮,则需要遍历剩下所有动物,如果该猫后面不再有狗,说明所有狗已经喂完;如果还有狗,则会因为该猫被阻塞而无法成功投喂该猫后的所有狗。

AC代码

Java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Main {
	
	public static void main(String[] args) throws IOException {
		InputReader in = new InputReader(System.in);
		PrintWriter out = new PrintWriter(System.out);
		
		int t = in.nextInt();
		int n = 0;
		long d = 0;
		long c = 0;
		long m = 0;
		boolean flag = false;
		
		char[] ch;
		
		for(int i = 1; i <= t; i++) {
			n = in.nextInt();
			d = in.nextLong();
			c = in.nextLong();
			m = in.nextLong();
			
			ch = in.next().toCharArray();
			
			flag = false;
			for(int j = 0; j < n; j++) {
				if(ch[j] == 'D') {
					d--;
					c += m;	// 每喂一条狗,猫粮增加 m
				}
				else {
					c--;
				}
				
				if(d < 0) {	// 当 d < 0,说明刚才那条狗投喂失败
					flag = true;
					break;
				}
				else if(c < 0) {	// 当猫粮没了,喂动物受阻,判断猫后面是否还有狗
					for(; j < n; j++) {
						if(ch[j] == 'D') {	// 如果猫后面还有狗说明狗不能全部喂完
							flag = true;
							break;
						}
					}
				}
			}
			
			if(flag) out.println("Case #" + i + ": NO");
			else out.println("Case #" + i + ": YES");
		}
		
		out.flush();
	}
	
	public static class InputReader {
		BufferedReader reader;
		StringTokenizer tokenizer;
		
		public InputReader(InputStream in) {
			reader = new BufferedReader(new InputStreamReader(in));
		}
		
		public String next() throws IOException {
			while(tokenizer == null || !tokenizer.hasMoreTokens()) {
				tokenizer = new StringTokenizer(reader.readLine());
			}
			return tokenizer.nextToken();
		}
		
		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}
		
		public Long nextLong() throws IOException {
			return Long.parseLong(next());
		}
	}

}

c++

#include<bits/stdc++.h>

using namespace std;

int main()
{
    long t, n, d, c, m;
    string s;
    bool flag;

    cin >> t;

    for(int i = 1; i <= t; i++)
    {
        cin >> n >> d >> c >> m;
        cin >> s;

        flag = false;

        for(int j = 0; j < n; j++)
        {
            if(s[j] == 'D')
            {
                d--;
                c += m; // 每喂一条狗,猫粮增加 m
            }
            else
            {
                c--;
            }

            if(d < 0)   // 当 d < 0,说明刚才那条狗投喂失败
            {
                flag = true;
                break;
            }
            else if(c < 0)  // 当猫粮没了,喂动物受阻,判断猫后面是否还有狗
            {
                for(; j < n; j++)
                {
                    if(s[j] == 'D') // 如果猫后面还有狗说明狗不能全部喂完
                    {
                        flag = true;
                        break;
                    }
                }
            }
        }

        if(flag) cout << "Case #" << i << ": NO" << endl;
        else cout << "Case #" << i << ": YES" << endl;
    }

    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值