HDU 1498 50 years, 50 colors(多次进行最小点覆盖运算)

本文介绍了一种解决在特定矩形区域内,根据颜色和扎气球次数限制,判断是否存在无法完全扎破的气球的问题的算法。通过最小点覆盖运算,实现了在给定条件下对气球扎破状态的判断。
部署运行你感兴趣的模型镜像
/*
题意:n*n的矩形中放入颜色值为[1,50]的气球,要求每一个人扎k次,每扎一次,可以将同行或者同列相同颜色的气球全部扎破。求是否存在不可能全部扎破的气球,按照升序规律输出气球的颜色。

题解:多次进行最小点覆盖运算即可
矩形行列分别为集合A和集合B,如果判断k气球,则如果map[i][j] = k,则表示存在一条边,这样便可以转换成最小点覆盖问题,只需要找出最小的点,清除掉两集合之间所有的边即可。
*/

#include <iostream>
#define re(i, n) for(int i = 0; i < n; ++ i)
using namespace std;

const int nMax = 105;
int map[nMax][nMax];
int link[nMax];
int useif[nMax];
int ans[nMax];
int len;
int n, k;

int dfs(int t, int col)
{
	re(i, n)
	{
		if(!useif[i] && map[t][i] == col)
		{
			useif[i] = 1;
			if(link[i] == -1 || dfs(link[i], col))
			{
				link[i] = t;
				return 1;
			}
		}
	}
	return 0;
}

int maxMatch(int col)
{
	memset(link, -1, sizeof(link));
	int num = 0;
	re(i, n)
	{
		memset(useif, 0, sizeof(useif));
		if(dfs(i, col)) num ++;
	}
	return num;
}

int main()
{
	//freopen("f://data.in", "r", stdin);
	while(scanf("%d %d", &n, &k) != EOF)
	{
		memset(map, 0, sizeof(map));
		len = 0;
		if(!n && !k) break;
		re(i, n) re(j, n) scanf("%d", &map[i][j]);
		for(int i = 1; i <= 50; ++ i)
		{
			if(maxMatch(i) > k)
				ans[len ++] = i;
		}
		if(!len) 
			printf("-1\n");
		else
		{
			re(i, len - 1) printf("%d ", ans[i]);
			printf("%d\n",ans[len - 1]);
		}
	}
	return 0;
}

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

### 2024 HDU运算 示例 教程 #### 什么是位运算? 位运算是指对二进制数中的每一位进行操作。常见的位运算符包括按位 (`&`)、按位或 (`|`)、按位异或 (`^`)、左移 (`<<`) 和右移 (`>>`)。 #### 杭州电子科技大学(HDU)位运算题目解析 对于给定的代码片段: ```cpp for (int i = 1; i < (1 << n); i++) { if ((i >> 1) & i) continue; } ``` 这段代码用于遍历 `n` 个元素的所有子集,并过滤掉某些特定条件下的子集。具体解释如下: - `(1 << n)` 表示将数字 `1` 左移 `n` 位,相当于计算 \(2^n\) 的值[^3]。 - `i >> 1` 将变量 `i` 右移一位,相当于除以 2。 - `(i >> 1) & i` 判断当前子集中是否存在相邻位置都为 1 的情况。如果存在,则跳过该次循环。 #### 实际应用案例 假设有一个数组 `[a, b, c]`,即 `n=3`,则上述代码会生成并筛选这些子集: - 子集表示法:`{}` 对应于二进制 `000` - `{a}` 对应于二进制 `001` - `{b}` 对应于二进制 `010` - `{c}` 对应于二进制 `100` - `{a, b}` 对应于二进制 `011` (被过滤) - `{a, c}` 对应于二进制 `101` - `{b, c}` 对应于二进制 `110` (被过滤) - `{a, b, c}` 对应于二进制 `111` (被过滤) 通过这种方式,可以有效地排除那些不符合特定条件的组合。 #### Python 中的位运算示例 以下是类似的逻辑在 Python 中的实现方式: ```python def generate_subsets(n): result = [] for i in range(1, 1 << n): # 遍历所有可能的子集 if not (i & (i - 1)): # 过滤掉含有连续 '1' 的子集 subset = [j for j in range(n) if (i >> j) & 1] result.append(subset) return result print(generate_subsets(3)) ``` 此函数将会输出符合条件的子集列表。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值