[WC2025] 猫粮

\(n\) 只猫猫,每只猫猫都要吃至少 \(m\) 克猫粮才能吃饱。

\(n\) 袋优质猫粮,第 \(i\) 袋优质猫粮的克数为 \(a_i\)。你还有 \(n\) 袋普通猫粮,第 \(i\) 袋普通猫粮的克数为 \(b_i\)

优质猫粮的味道很好,当你打开一袋优质猫粮后,所有没有吃饱的猫猫都会来抢,其中的任何一只猫猫都可能抢走这袋猫粮。普通猫粮味道一般,当你喂给一只猫猫后,不会有别的猫猫来抢。

你需要判断是否存在一种方法,可以喂饱所有的猫猫。

\(T \leq 50\) 组数据,\(1 \leq n \leq 40000\)\(2 \leq m \leq 10^5\)。保证 \(1 \leq a_i,b_i \leq m-1\),且 \(\sum\limits_{i=1}^{n} a_i + \sum\limits_{i=1}^{n} b_i = nm\)

由题目的数据范围限制,可知在喂饱所有的猫猫的情况下,所有猫粮不能产生浪费。同时一只猫猫吃一袋猫粮一定不够,我们可以得到结论:每只猫猫都要吃恰好两袋猫粮。

考虑将 \(a_i+b_j=m\) 的猫粮配对,假设配成的对数为 \(x\),接下来分类讨论:

  • \(x=n\),此时我们只需要先打开一袋优质猫粮,当一只猫猫吃了这袋猫粮后,把对应的普通猫粮喂给这只猫猫即可。这样一定是有解的。

  • \(x=n-2\),此时我们喂完其他的猫猫后不能使用刚才的策略,考虑使用两袋普通猫粮和两袋优质猫粮分别喂饱两只猫猫。此时要求两袋普通猫粮和两袋优质猫粮的和均为 \(m\)

  • \(x<n-2\),此时剩下多组未匹配的猫粮,无法使用第一种情况的方法,我们只能先让普通猫粮互相配对。此时一定要求 \(2 \mid n-x\),接下来只需要普通猫粮能配成若干对即可。然后你需要保证优质猫粮互相没有区别,即 \(2 \mid m\) 且剩下每袋优质猫粮都是 \(\dfrac{m}{2}\)

结束了。

#include<iostream>
#include<cstdio>
using namespace std;
int cnt_a[100010],cnt_b[100010],cnt_tmp_a[100010],cnt_tmp_b[100010];
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		int n,m;
		scanf("%d %d",&n,&m);
		for(int i=1;i<m;i++){
			cnt_a[i]=cnt_b[i]=cnt_tmp_a[i]=cnt_tmp_b[i]=0;
		}
		for(int i=1;i<=n;i++){
			int num;
			scanf("%d",&num);
			cnt_a[num]++;
		}
		for(int i=1;i<=n;i++){
			int num;
			scanf("%d",&num);
			cnt_b[m-num]++;
		}
		int x=0;
		for(int i=1;i<m;i++){
			x+=min(cnt_a[i],cnt_b[i]);
			cnt_tmp_a[i]+=cnt_a[i]-min(cnt_a[i],cnt_b[i]);
			cnt_tmp_b[i]+=cnt_b[i]-min(cnt_a[i],cnt_b[i]);
		}
		if(x==n){
			printf("Yes\n");
		}
		else if(x==n-2){
			int sum_a=0,sum_b=0;
			for(int i=1;i<m;i++){
				for(int j=1;j<=cnt_tmp_a[i];j++){
					sum_a+=i;
				}
				for(int j=1;j<=cnt_tmp_b[i];j++){
					sum_b+=i;
				}
			}
			if(sum_a==m  &&  sum_b==m){
				printf("Yes\n");
			}
			else{
				printf("No\n");
			}
		}
		else{
			bool flag=true;
			if((n-x)%2!=0){
				flag=false;
			}
			if(m%2!=0){
				flag=false;
			}
			for(int i=1;i<m;i++){
				if(cnt_tmp_b[i]!=cnt_tmp_b[m-i]){
					flag=false;
				}
			}
			if(cnt_tmp_a[m/2]!=n-x){
				flag=false;
			}
			if(flag){
				printf("Yes\n");
			}
			else{
				printf("No\n");
			}
		}
	}
	return 0;
}
posted @ 2025-12-24 00:31  Oken喵~  阅读(5)  评论(0)    收藏  举报