HDU 2236 无题II //MaxMatch

本文介绍了一个基于矩阵的游戏问题,目标是在一个n*n的矩阵中寻找n个不同行和列的元素,使得这些元素的最大值与最小值之差尽可能小。文章提供了详细的算法实现,包括如何通过枚举差值和最小点集覆盖来解决问题。

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

 

无题II

Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 214    Accepted Submission(s): 102


Problem Description
这是一个简单的游戏,在一个n*n的矩阵中,找n个数使得这n个数都在不同的行和列里并且要求这n个数中的最大值和最小值的差值最小。
 

Input
输入一个整数T表示T组数据。
对于每组数据第一行输入一个正整数n(1<=n<=100)表示矩阵的大小。
接着输入n行,每行n个数x(0<=x<=100)。
 

Output
对于每组数据输出一个数表示最小差值。
 

Sample Input
  
  
1 4 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4
 

Sample Output
  
  
3
 

Author
xhd
 

Source
 

Recommend
lcy
 

Statistic |  Submit |  Discuss | Back

 

枚举差值+最小点集覆盖

 

#include<stdio.h>

#include<string.h>

int a[101][101];

bool map[101][101],usedif[101];

int link[101];

int maxn,minn,fir,last,n;

bool can(int t)

{

    for(int i=0;i<n;i++)

    if(usedif[i]==false&&map[t][i]==true)

    {

        usedif[i]=true;

        if(link[i]==-1||can(link[i]))

        {

            link[i]=t;

            return true;

        }

    }

    return false;

}

bool MaxMatch()

{

    for(int i=0;i<n;i++)

      for(int j=0;j<n;j++)

        if(a[i][j]>=fir&&a[i][j]<=last)  map[i][j]=true;

        else  map[i][j]=false;

    memset(link,-1,sizeof(link));

    for(int i=0;i<n;i++)

    {

        memset(usedif,false,sizeof(usedif));

        if(!can(i)) return false;

    }

    return true;

}

int solve()

{

    fir=minn;

    last=maxn;

    int min=1<<25-1;

    while(fir>=0&&fir<=last)

    {

        if(MaxMatch())

        {

            if(min>last-fir) min=last-fir;

            fir++;

        }

        else

        {

            last--;

            fir--;

        }

    }

    //for(int i=0;i<n;i++)  printf("%d/n",link[i]);

    return min;

}

int main()

{

    int T;

    scanf("%d",&T);

    while(T--)

    {

        scanf("%d",&n);

        maxn=-1,minn=1<<25-1;

        for(int i=0;i<n;i++)

          for(int j=0;j<n;j++)

          {

              scanf("%d",&a[i][j]);

              if(a[i][j]>maxn) maxn=a[i][j];

              if(a[i][j]<minn) minn=a[i][j];

          }

        printf("%d/n",solve());

    }

    return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值