• hdu 2236


    题目:

    Problem Description
    这是一个简单的游戏,在一个n*n的矩阵中,找n个数使得这n个数都在不同的行和列里并且要求这n个数中的最大值和最小值的差值最小。
     
    Input
    输入一个整数T表示T组数据。
    对于每组数据第一行输入一个正整数n(1<=n<=100)表示矩阵的大小。
    接着输入n行,每行n个数x(0<=x<=100)。
     
    Output
    对于每组数据输出一个数表示最小差值。
     
    分析:要在不同行不同列中找n个数,很容易想到用二分匹配。但是要这n个数的最大值和最小值的差值最小就比较麻烦了。其实,这个时候应该要想想枚举的方法能不能做得出这个题目了。枚举差值,再在每一个差值里面枚举长度为这个差值的区间。在枚举差值的过程还能用二分法来加速,若在该差值的限制下找到符合题意的匹配就将差值的枚举范围缩为[min,mid],否则缩为[mid,max]。
     
    View Code
     1 #include<cstdio>
     2 int mat[2][100],nx,ny,vmax,vmin,min,max,mid,p;
     3 bool visited[100],matrix[100][100];
     4 int path(int u)
     5 {
     6     int i;
     7     for(i=0;i<ny;i++)
     8     {
     9         if(matrix[u][i]>=p && matrix[u][i]<=p+mid && !visited[i])
    10         {
    11             visited[i]=true;
    12             if(mat[1][i]==-1 || path(mat[1][i]))
    13             {
    14                 mat[0][u]=i;
    15                 mat[1][i]=u;
    16                 return 1;
    17             }
    18         }
    19     }
    20     return 0;
    21 }
    22 bool Hungary()
    23 {
    24     int i,j;
    25     for(i=0;i<nx;i++)
    26         mat[0][i]=-1;
    27     for(i=0;i<ny;i++)
    28         mat[1][i]=-1;
    29     for(i=0;i<nx;i++)
    30     {
    31         for(j=0;j<ny;j++)
    32             visited[j]=false;
    33         if(path(i)==0)
    34             return false;
    35     }
    36     return true;
    37 }
    38 int main()
    39 {
    40     int t;
    41     scanf("%d",&t);
    42     while(t--)
    43     {
    44         scanf("%d",&nx);
    45         ny=nx;
    46         vmax=0;
    47         vmin=0xffffff;
    48         for(int i=0;i<nx;i++)
    49         {
    50             for(int j=0;j<ny;j++)
    51             {
    52                 scanf("%d",&matrix[i][j]);
    53                 if(matrix[i][j]>vmax)
    54                     vmax=matrix[i][j];
    55                 if(matrix[i][j]<vmin)
    56                     vmin=matrix[i][j];
    57             }
    58         }
    59         max=vmax-vmin;
    60         min=0;
    61         while(true)
    62         {
    63             mid=(min+max)/2;
    64             bool flag=false;
    65             for(p=vmin;p+mid<=vmax;p++)
    66             {
    67                 if(Hungary())
    68                 {
    69                     flag=true;
    70                     break;
    71                 }
    72             }
    73             if(flag)
    74                 max=mid;
    75             if(mid==min)
    76                 break;
    77             if(!flag)
    78                 min=mid;
    79         }
    80         printf("%d\n",max);
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    ACM第六周竞赛题目——A LightOJ 1317
    数学概念——J
    数学概念——I
    数学概念——D 期望
    数学概念——A 几何概型
    数学概念——E 期望(经典问题)
    数学概念——F 概率(经典问题)birthday paradox
    数学概念——H 最美素数
    数学概念——G 最大公约数
    UVa1328
  • 原文地址:https://www.cnblogs.com/ZShogg/p/2964000.html
Copyright © 2020-2023  润新知