[暴力搜索]poj1231 The Alphabet Game

The Alphabet Game
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 1442 Accepted: 586

Description

Little Dara has recently learned how to write a few letters of the English alphabet (say k letters). He plays a game with his little sister Sara. He draws a grid on a piece of paper and writes p instances of each of the k letters in the grid cells. He then asks Sara to draw as many side-to-side horizontal and/or vertical bold lines over the grid lines as she wishes, such that in each rectangle containing no bold line, there would be p instances of one letter or nothing. For example, consider the sheet given in Figure 1, where Sara has drawn two bold lines creating four rectangles meeting the condition above. Sara wins if she succeeds in drawing the required lines. Dara being quite fair to Sara, wants to make sure that there would be at least one solution to each case he offers Sara. You are to write a program to help Dara decide on the possibility of drawing the right lines. 

Input

The first line of the input file contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case consists of two integers k (1 <= k <= 26), the number of different letters, and p (1 <= p <= 10), the number of instances of each letter. Followed by the first line, there are k lines, one for each letter, each containing p pairs of integers (xi, yi) for 1 <= i <= p. A pair indicates coordinates of the cell on the paper where one instance of the letter is written. The coordinates of the upper left cell of the paper is assumed to be (1,1). Coordinates are positive integers less than or equal to 1,000,000. You may assume that no cell contains more than one letter. 

Output

There should be one line per test case containing a single word YES or NO depending on whether the input paper can be divided successfully according to the constraints stated in the problem. 

Sample Input

2
3 2
6 4 8 4
4 2 2 1
2 3 2 4
3 3
1 1 3 1 5 1
2 1 4 1 6 1
2 2 4 2 8 1

Sample Output

YES
NO

Source



题意:

纸的左上角单元格被假定为(1,1);
用直线分割矩形,直线数量不作要求,要求被分割的矩形内,可以没有字母或者有p个同一字母;

满足要求输出"YES",否则输出"NO";

思路:

用结构体记录每一种字母所在最小矩阵的左上角坐标和右下角坐标;

然后跟其他矩阵对比,扩展这个矩阵所记录的坐标,使之不矛盾(其实就是记录切割直线);

最后判断矩阵之间是否有重合;

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
/*
记录直线
*/
#define inf 1<<29
struct{
    int up, left;//左上角
    int down, right;//右下角
}e[30];
int t, k, p;
int judge()
{
    int i, j;
    for(i = 1; i <= k; i++)
    for(j = 1; j <= k; j++)
        if(i != j)
        {
            if(((e[i].left>=e[j].left && e[i].left<=e[j].right)
            ||(e[i].right>=e[j].left && e[i].right<=e[j].right))
            &&((e[i].up>=e[j].up && e[i].up<=e[j].down)
            ||(e[i].down>=e[j].up && e[i].down<=e[j].down)))
                return 0;
        }
    return 1;
}
int main()
{
    int i, j;
    int a, b;
    scanf("%d", &t);
    while(t-->0)
    {
        //录入数据
        scanf("%d%d", &k, &p);
        for(i = 1; i <= k; i++)
        {
            e[i].up = e[i].left = inf;
            e[i].down = e[i].right = 0;
            for(j = 1; j <= p; j++)
            {
                scanf("%d%d", &a, &b);
                e[i].up = min(e[i].up, a);//横坐标
                e[i].left = min(e[i].left, b);//纵坐标
                e[i].down = max(e[i].down, a);
                e[i].right = max(e[i].right, b);
            }
        }
        //更新直线的位置,就是扩展矩阵范围
        for(i = 1; i <= k; i++)
            if(i != j)
            {
                if(e[i].left>e[j].left && e[i].left<e[j].right)
                    e[i].left = e[j].left;
                if(e[i].right>e[j].left && e[i].right<e[j].right)
                    e[i].right = e[j].right;
                if(e[i].up>e[j].up && e[i].up<e[j].down)
                    e[i].up = e[j].up;
                if(e[i].down>e[j].up && e[i].down<e[j].down)
                    e[i].down = e[j].down;
            }
        //判断是否有重合
        int t = judge();
        if(t)
            printf("YES\n");
        else
            printf("NO\n");
    }
}
/*
2
3 2
6 4 8 4
4 2 2 1
2 3 2 4
3 3
1 1 3 1 5 1
2 1 4 1 6 1
2 2 4 2 8 1
-----------
YES
NO
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值