`

hdu 1507 Uncle Tom's Inherited Land*

阅读更多

Uncle Tom's Inherited Land*

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 4   Accepted Submission(s) : 2
Special Judge
Problem Description
Your old uncle Tom inherited a piece of land from his great-great-uncle. Originally, the property had been in the shape of a rectangle. A long time ago, however, his great-great-uncle decided to divide the land into a grid of small squares. He turned some of the squares into ponds, for he loved to hunt ducks and wanted to attract them to his property. (You cannot be sure, for you have not been to the place, but he may have made so many ponds that the land may now consist of several disconnected islands.)

Your uncle Tom wants to sell the inherited land, but local rules now regulate property sales. Your uncle has been informed that, at his great-great-uncle's request, a law has been passed which establishes that property can only be sold in rectangular lots the size of two squares of your uncle's property. Furthermore, ponds are not salable property.

Your uncle asked your help to determine the largest number of properties he could sell (the remaining squares will become recreational parks).


 

Input
Input will include several test cases. The first line of a test case contains two integers N and M, representing, respectively, the number of rows and columns of the land (1 <= N, M <= 100). The second line will contain an integer K indicating the number of squares that have been turned into ponds ( (N x M) - K <= 50). Each of the next K lines contains two integers X and Y describing the position of a square which was turned into a pond (1 <= X <= N and 1 <= Y <= M). The end of input is indicated by N = M = 0.

 

Output
For each test case in the input your program should first output one line, containing an integer p representing the maximum number of properties which can be sold. The next p lines specify each pair of squares which can be sold simultaneity. If there are more than one solution, anyone is acceptable. there is a blank line after each test case. See sample below for clarification of the output format.

 

Sample Input
4 4 6 1 1 1 4 2 2 4 1 4 2 4 4 4 3 4 4 2 3 2 2 2 3 1 0 0

 

Sample Output
4 (1,2)--(1,3) (2,1)--(3,1) (2,3)--(3,3) (2,4)--(3,4) 3 (1,1)--(2,1) (1,2)--(1,3) (2,3)--(3,3)
 
          题目大意:给你一个矩形,然后输入矩形里面池塘的坐标(不能放东西的地方),问可以放的地方中,最多可以放多少块1*2的长方形方块,并输出那些方块的位置。
          这道题感觉出得很好,平时经常会遇到这些问题,但是不知道怎么解决。这个问题就是二分匹配,用匈牙利算法可以搞定,问题就是如何建图,相邻连着的就可以加一条边。这样建图后,最大匹配就是最大值。坐标就是他的pre[]这样问题就解决了。
代码:
#include <iostream>
#include <stdio.h>
#include <memory.h>
using namespace std;

const int N = 105;

int pre[N*N], map[N*N];
bool flag[N*N], vis[N*N];
int n, m, total;

int find(int cur)
{
    int k;
    k = cur + 1;
    if(cur%m+1 < m && k < total && map[k] != -1 && !flag[k])
    {
        flag[k] = true;
        if(pre[k] == -1 || find(pre[k]))
        {
            pre[k] = cur;
            return 1;
        }
    }
    k = cur + m;
    if(k < total && map[k] != -1 && !flag[k])
    {
        flag[k] = true;
        if(pre[k] == -1 || find(pre[k]))
        {
            pre[k] = cur;
            return 1;
        }
    }
    k = cur - 1;
    if(cur%m > 0 && k >= 0 && map[k] != -1 && !flag[k])
    {
        flag[k] = true;
        if(pre[k] == -1 || find(pre[k]))
        {
            pre[k] = cur;
            return 1;
        }
    }
    k = cur - m;
    if(k >= 0 && map[k] != -1 && !flag[k])
    {
        flag[k] = true;
        if(pre[k] == -1 || find(pre[k]))
        {
            pre[k] = cur;
            return 1;
        }
    }
    return 0;
}

int main()
{
    int i, k, t, x, y, sum;
    while(scanf("%d %d", &n, &m), n && m)
    {
        total = n * m;
        memset(vis, false, sizeof(vis));
        memset(map, -1, sizeof(map));
        memset(pre, -1, sizeof(pre));
        for(i = 0; i < total; i++)
        {
            map[i] = i;
        }
        scanf("%d", &t);
        while(t--)
        {
            scanf("%d %d", &x, &y);
            k = (x-1)*m + (y-1);
            map[k] = -1;
        }
        sum = 0;
        for(i = 0; i < total; i++)
        {
            if(map[i] != -1)
            {
                memset(flag, false, sizeof(flag));
                sum += find(map[i]);
            }
        }
        printf("%d\n", sum/2);
        for(i = 0; i < total; i++)
        {
            if(map[i] != -1 && pre[i] != -1 && !vis[pre[i]] && !vis[i])
            {
                vis[pre[i]] = vis[i] = true;
                printf("(%d,%d)--(%d,%d)\n", i/m+1, i%m+1, pre[i]/m+1, pre[i]%m+1);
            }
        }
        printf("\n");
    }

    return 0;
}
 
  • 大小: 6.2 KB
0
0
分享到:
评论

相关推荐

    二分匹配题集

    7. **Uncle Tom's Inherited Land (HDU 1507)** - **知识点**:黑白染色+奇偶匹配问题。 - **解题思路**:构建二分图模型,将区域染成黑白两种颜色,使用最大匹配算法求解奇偶匹配问题。 8. **Card Game Cheater...

    KM匹配题集

    - **【POJ 3565】Ants**、**【POJ 3686】The Windy's**:题目中的“最小权值匹配”暗示需要解决匹配问题,可能涉及Kuhn-Munkres算法。 - **【ZOJ 2342】Roads**、**【不等式】**:这些题目可能涉及到图论中的最短路...

    hdu.rar_hdu

    HDU(杭州电子科技大学在线评测系统)是一个深受程序员喜爱的在线编程练习平台,它提供了丰富的算法题目供用户挑战,帮助他们提升编程技能和算法理解能力。"hdu.rar_hdu"这个压缩包文件很可能是某位程序员整理的他在...

    HDU题目java实现

    【标题】"HDU题目java实现"所涉及的知识点主要集中在使用Java编程语言解决杭州电子科技大学(HDU)在线评测系统中的算法问题。HDU是一个知名的在线编程竞赛平台,它提供了大量的算法题目供参赛者练习和提交解决方案...

    hdu题目分类

    ### hdu题目分类知识点概述 本篇将对“hdu题目分类”中提及的各种类型问题进行详细介绍,旨在帮助读者更好地理解这些题目所涉及的核心概念和技术点,并为编程竞赛中的实战训练提供参考。以下是对每道题目的具体分析...

    hdu1250高精度加法

    ### hdu1250高精度加法 #### 背景介绍 在计算机科学与编程竞赛中,处理大整数运算(特别是加法、减法、乘法等)是常见的需求之一。当数字的位数超过了标准数据类型(如`int`、`long`等)所能表示的最大值时,就需要...

    ACM HDU

    【ACM HDU】指的是在ACM(国际大学生程序设计竞赛,International Collegiate Programming Contest)中,参赛者在杭州电子科技大学(Hangzhou Dianzi University,简称HDU)的在线评测系统上完成并已解决的题目集合...

    HDU_2010.rar_hdu 2010_hdu 20_hdu acm20

    【标题】"HDU_2010.rar"是一个压缩包文件,其中包含了与"HDU 2010"相关的资源,特别是针对"HDU ACM20"比赛的编程题目。"hdu 2010"和"hdu 20"可能是该比赛的不同简称或分类,而"hdu acm20"可能指的是该赛事的第20届...

    HDU DP动态规划

    【标题】"HDU DP动态规划"涉及到的是在算法领域中的动态规划(Dynamic Programming,简称DP)技术,这是解决复杂问题的一种高效方法,尤其适用于有重叠子问题和最优子结构的问题。动态规划通常用于优化多阶段决策...

    杭电ACMhdu1163

    【标题】:杭电ACMhdu1163 【描述】:这是一道源自杭州电子科技大学(Hangzhou Dianzi University,简称HDU)的ACM编程竞赛题目,编号为1163。这类问题通常需要参赛者利用计算机编程解决数学、逻辑或算法上的挑战,...

    欧拉回路题集

    6. **King Arthur's Knights (4337) 任意一个点度 d(u)&gt;= (n+1)/2, 则一定存在哈密顿回路** - **题目描述**:与前面提到的SGU-122类似。 - **解题思路**:通过分析图的性质来证明。 - **数据结构**:无需特别的...

    ACM HDU题目分类

    ACM HDU 题目分类 ACM HDU 题目分类是指对 HDU 在线判题系统中题目的分类,总结了大约十来个分类。这些分类将有助于编程选手更好地理解和解决问题。 DP 问题 DP(Dynamic Programming,动态规划)是一种非常重要...

    解题代码 hdu1241

    scanf("%s", graph + i); } for (i = 0; i ; i++) { for (j = 0; j ; j++) { if (graph[i][j] == '@') { sum++; // 统计岛屿数量 dfs(i, j); // 对岛屿进行搜索 } } } printf("%d\n", sum); } return 0...

    Hdu1000—2169部分代码

    HDU是杭州电子科技大学(Hangzhou Dianzi University)举办的一个在线编程竞赛平台,全称为HDU Online Judge。ACM是国际大学生程序设计竞赛(International Collegiate Programming Contest)的缩写,是一个全球性的...

    hdu动态规划算法集锦

    根据提供的信息,我们可以总结出以下关于“hdu动态规划算法集锦”的知识点: ### 动态规划基础概念 动态规划是一种解决多阶段决策问题的方法,它通过将原问题分解为互相重叠的子问题,利用子问题的解来构建原问题...

    HDU1059的代码

    HDU1059的代码

    HDU最全ac代码

    HDU(Hangzhou Dianzi University)是国内外知名的在线编程竞赛平台,主要服务于ACM/ICPC(国际大学生程序设计竞赛)以及相关的算法训练。"HDU最全ac代码"这个压缩包很可能是包含了在HDU平台上解题通过的完整源代码...

    hdu1001解题报告

    hdu1001解题报告

    ACM HDU 2000-2099 解题报告 杭电 ACM

    《ACM HDU 2000-2099 解题报告 杭电 ACM》是一份详尽的编程竞赛解题集,主要涵盖了杭电(Hangzhou Dianzi University)在线判题系统(HDU OJ)上的2000至2099号题目。这份解题报告是针对参与ACM/ICPC(国际大学生...

    hdu 1574 passed sorce

    hdu 1574 passed sorce

Global site tag (gtag.js) - Google Analytics