A - Cats and Fish

Time limit Memory limit

1000 ms 262144 kB

There are many homeless cats in PKU campus. They are all happy because the students in the cat club of PKU take good care of them. Li lei is one of the members of the cat club. He loves those cats very much. Last week, he won a scholarship and he wanted to share his pleasure with cats. So he bought some really tasty fish to feed them, and watched them eating with great pleasure. At the same time, he found an interesting question:

There are m fish and n cats, and it takes ci minutes for the ith cat to eat out one fish. A cat starts to eat another fish (if it can get one) immediately after it has finished one fish. A cat never shares its fish with other cats. When there are not enough fish left, the cat which eats quicker has higher priority to get a fish than the cat which eats slower. All cats start eating at the same time. Li Lei wanted to know, after x minutes, how many fish would be left.

Input

There are no more than 20 test cases.

For each test case:

The first line contains 3 integers: above mentioned m, n and x (0 < m <= 5000, 1 <= n <= 100, 0 <= x <= 1000).

The second line contains n integers c1,c2 … cn,  ci means that it takes the ith cat ci minutes to eat out a fish ( 1<= ci <= 2000).

Output

For each test case, print 2 integers p and q, meaning that there are p complete fish(whole fish) and q incomplete fish left after x minutes.

Sample Input

2 1 1
1
8 3 5
1 3 4
4 5 1
5 4 3 2 1

Sample Output

1 0
0 1
0 3

题目意思:

有m条鱼,n只猫,给出n只猫吃一条鱼的时间,问x分钟后剩余多少条完好的鱼,剩余多少条被猫啃过的鱼。

解题思路1(错的,有问题):

一开始没算复杂度,没想到模拟可以过,有什么方法可以很快直接算出答案,想了这个办法,正好还过了所有样例。算出x分钟内每只猫完整吃掉的鱼有多少条(即x整除每只猫吃鱼的时间),求个和,如果和大于m则说明鱼已经被吃完了(这里有问题),p = 0,否则,p = m-和。然后之前算每只猫x时间内吃多少条完整的鱼时,会记录一下x分钟后有多少猫是不能完整吃完一条鱼的。然后q就是 剩余完整的鱼 和 猫吃的不完整的鱼总和 中取最小,因为到最后要么是鱼不够给猫吃,要么是鱼多了猫吃不过来,最后把剩余完整的鱼减去被吃一半的鱼就是最终剩余不完整的鱼。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main(){
	int n,m,x;
	while(cin>>m>>n>>x) {
		int q,p;
		q = p = 0;
		for(int i = 0; i < n; i++){
			int ci;
			scanf("%d",&ci);
			p += (x/ci);	//x分钟后每只猫完整吃掉的鱼的和 
			if( (x % ci) != 0)	//判断每只猫在x分钟后会不会还没吃完鱼 
				q++;
		}
		p = m-p;	//鱼的总数-(x分钟后每只猫完整吃掉的鱼的和 )  
		if(p < 0) p = 0;	//如果小于0,就是0
		q = min(q,p);		//不完整的鱼,是猫吃不完的鱼总和与剩余鱼取最小 
		p-=q;	//最后完整的鱼还需要减去不完整的鱼,才是最终答案 
		cout<<p<<" "<<q	<<endl;
	}
	return 0;
}

 

错误的点:

没考虑到吃的慢的猫可能没吃完,但是吃的快的猫能全吃完
    例如:
    3 2 3
    1 5
    3条鱼,2只猫,问3分钟后剩多少条完整的鱼,多少条不完整的鱼。按照我说的这个思路,第一只吃的快的猫,会把所有的鱼吃掉,但是应该有一条鱼是第二只猫吃,还没吃完,第一只猫按照题意是不能抢的。

    后来看了别人的博客(https://blog.csdn.net/ZCY19990813/article/details/99622728),发现是模拟,才发现数据不大,模拟一遍时间复杂度也不高,不过在拿别人AC代码对拍时,发现了不一样的结果,但是我第一个思路的代码是对的,别人的AC代码反而有问题,仔细了一下,发现了他的问题,他是没完整的鱼就直接退出,如果有鱼,且猫没在吃,就喂,这就出现了一个问题,就是没有完整的鱼了,但是猫在吃的鱼,可以在x分钟吃完,可是退出了,导致没吃完,
    例如:
    2 3 7
    7 3 9
    这组数组我认为答案应该是0 0
    但是别人的代码跑出来的答案是0 2
    所以我换了种写法


解题思路:

先对猫吃鱼的时间进行排序(因为在鱼不够的时候,吃的快的猫优先),直接进行模拟x分钟,当有鱼且猫没在吃,就喂,并将猫的状态变为在吃鱼,当时间为猫吃鱼时间的倍数时,猫吃完鱼。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int cat[105],eat[105]; 
int main(){
	int n,m,x;
	while(cin>>m>>n>>x) {
		for(int i = 0; i < n; i++){
			cat[i] = eat[i] = 0;
		} 
		int q,p;
		q = p = 0;
		for(int i = 0; i < n; i++){
			scanf("%d",&cat[i]);
		}
		sort(cat,cat+n);
		for(int i = 1; i <=x ; i++){
			for(int j = 0; j < n; j++){
				if(m && eat[j] == 0){	//当有完整的鱼,且猫没在吃鱼的时候 
					m--;	//猫吃鱼 
					eat[j] = 1;		//猫变为吃鱼的状态 
				}
				if((i%cat[j])==0){		//如果时间是猫吃鱼时间的倍数 
					eat[j] = 0;
				}
			}
		}
		for(int i = 0; i < n; i++){		//时间结束后统计有多少只猫还在吃鱼 
			if(eat[i] == 1) p++;
		}
		printf("%d %d\n",m,p); 		//输出结果 
	}
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值