HDU 1498 50 years, 50 colors

本文介绍了如何解决HDOJ 1498题目的算法,通过建立二分图模型解决气球颜色消除问题,采用最小顶点覆盖法找出无法完全消除的颜色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接 :http://acm.hdu.edu.cn/showproblem.php?pid=1498

题目大意:给出一个n*n的矩阵,矩阵每个元素代表一个气球的颜色。颜色取值范围是[1,50]。最多能进行k次操作,每次操作可以打掉某一行同种颜色的气球或者打掉某一列同种颜色的气球。问对于每一种颜色的气球经过k次操作是否能够消除完。

算法:首先,我们只考虑一种颜色的消除情况。

对于样例2

2 1
1 1
1 2

比如我们只考虑颜色1

那么其中的邻接矩阵应该为

1 1

1 0

对于某个气球,它的坐标为(x,y)

要消除它只需要操作x行或者y列,显然没必要同时进行这两个操作

同样的,我们建立二分图的模型

X集合为所有行号,Y集合为所有列号,每个坐标为一条边。

那么最后要求的是一个顶点集合,这个顶点集合要满足,所有边至少有一个顶点在这个顶点集合中,而且这个顶点集合要最小。其实这就是最小顶点覆盖,在二分图中最小顶点覆盖就等于最大匹配。

解决了最主要的问题,那么接下来的问题就轻松了,只要枚举每种颜色就行了,对于每一种颜色算出对应的最大匹配,如果大于k,这说明这种颜色经过k次操作是不可能消除完的,则把这个颜色记录在答案集合中去。

最后判断如果答案集合元素个数为0,表示每种出现过的颜色都可以被消除完。

否则排序之后输出答案。

下面是AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=105;
int Map[maxn][maxn],vis[maxn],girl[maxn],n,k;
int Find(int x,int color)
{
    for(int i=1;i<=n;i++)
    {
        if(!vis[i]&&Map[x][i]==color)
        {
            vis[i]=1;
            if(!girl[i]||Find(girl[i],color))
            {
                girl[i]=x;
                return true;
            }
        }
    }
    return false;
}
int match(int color)
{
    int ans=0;
    memset(girl,0,sizeof(girl));
    for(int i=1;i<=n;i++)
    {
        memset(vis,0,sizeof(vis));
        if(Find(i,color)) ans++;
    }
    return ans;
}
int main()
{
    while(~scanf("%d%d",&n,&k),n+k)
    {
        //memset(Map,0,sizeof(Map));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            scanf("%d",&Map[i][j]);//读入颜色矩阵
        vector<int>ans;//存最后不能被全部消除的颜色
        for(int i=1;i<=50;i++)//枚举每一种颜色
            if(match(i)>k) ans.push_back(i);//如果有颜色根本没出现过,那么它算出的最大匹配必为0显然会小于k
        if(ans.size()==0) printf("-1\n");
        else
        {
            sort(ans.begin(),ans.end());//排序,其实,也没必要排序,因为我们是从小到大枚举的,那么答案势必从小到大加进去的,肯定是有序的
            for(int i=0;i<ans.size()-1;i++) printf("%d ",ans[i]);
            printf("%d\n",ans[ans.size()-1]);
        }
    }
    return 0;
}



内容概要:本文详细探讨了基于MATLAB/SIMULINK的多载波无线通信系统仿真及性能分析,重点研究了以OFDM为代表的多载波技术。文章首先介绍了OFDM的基本原理和系统组成,随后通过仿真平台分析了不同调制方式的抗干扰性能、信道估计算法对系统性能的影响以及同步技术的实现与分析。文中提供了详细的MATLAB代码实现,涵盖OFDM系统的基本仿真、信道估计算法比较、同步算法实现和不同调制方式的性能比较。此外,还讨论了信道特征、OFDM关键技术、信道估计、同步技术和系统级仿真架构,并提出了未来的改进方向,如深度学习增强、混合波形设计和硬件加速方案。; 适合人群:具备无线通信基础知识,尤其是对OFDM技术有一定了解的研究人员和技术人员;从事无线通信系统设计与开发的工程师;高校通信工程专业的高年级本科生和研究生。; 使用场景及目标:①理解OFDM系统的工作原理及其在多径信道环境下的性能表现;②掌握MATLAB/SIMULINK在无线通信系统仿真中的应用;③评估不同调制方式、信道估计算法和同步算法的优劣;④为实际OFDM系统的设计和优化提供理论依据和技术支持。; 其他说明:本文不仅提供了详细的理论分析,还附带了大量的MATLAB代码示例,便于读者动手实践。建议读者在学习过程中结合代码进行调试和实验,以加深对OFDM技术的理解。此外,文中还涉及了一些最新的研究方向和技术趋势,如AI增强和毫米波通信,为读者提供了更广阔的视野。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值