星空

描述

Recently Little Hi started to like astronomy and downloaded the pictures of K constellations. He wonders how many of them he can spot in the night?

输入

Line 1: K(1 <= K <= 20), the number of constellations.
K constellation pictures follow. The format of each picture is:
Line 1 of each picture: H and W(5 <= H, W, <= 100), the height and width of the picture.
Line 2~H+1 of each picture: An H*W matrix of characters representing the picture of a constellation. Each line contains W characters. ‘#’ for a star and ‘.’ for empty area. There are no more than 20 stars in each constellation.
After K constellations is the sky Little Hi looks to in the night.
Line 1 of sky: N and M(100 <= N, M <= 1000), the size of the sky Little Hi looks to.
Line 2~N of sky: An N*M matrix of characters representing the sky Little Hi looks to. Each line contains M characters. ‘#’ for a star and ‘.’ for empty area. There are no more than 5000 stars in the sky.

输出

For each constellation in the Input output “Yes” or “No” indicating whether Little Hi can spot the constellation in the sky.
All pictures of constellations and the sky Little Hi looks to are in the same direction so there is no need to rotate the pictures.

提示

A constellation can be spoted if and only if all stars in the constellation can be matched in the sky. It is allowed that two spoted constellations share common stars.
原题见:http://hihocoder.com/contest/hiho71/problem/1

解法:
由于每个constellation中star最多有20个,可以将其位置坐标存储下来。然后判断时,枚举天空的每个位置为初始位置,判断偏移后的坐标是否为星,如果全部都符合,就输出yes。
这里有个坑,给的星图可能有大片空白,而提示中说道只要星星的位置匹配就行,下面看个例子:
星图为:
…….
……#
……#
sky为:
#
#
这种情况下可以找到星图的,但是整个星图是比sky还大的,因此我们要先将星图中的空白去除。也就是计算出现#的最小x,和最小y作为星图的相对起始点。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
enum {maxn = 1000+3};
char map[maxn][maxn];
struct star{
    int x, y;
};
struct star Const[23][23];
int starNum[24];
char str[100+4][100+4];
 int m, n;
 bool has(int i)
 {
     for (int y = 0; y < n; y++)
        for (int x =0; x< m; x++)
     {
         int k;
         for (k=0; k<starNum[i]; k++)
         {
             int nowX = x + Const[i][k].x;
             int nowY = y + Const[i][k].y;
             if (nowX >= m || nowY >= n || map[nowY][nowX] != '#')
                break;
         }
         if (k == starNum[i])
            return true;
     }
    return false;
 }
 //#define OJ
int main()
{
    #ifndef OJ
    freopen("in.txt", "r", stdin);
    #endif // OJ
    int k=0;
    scanf("%d", &k);
    for (int i=0; i< k; i++)
    {
        int h, w;
        scanf("%d %d", &h, &w);
        starNum[i] = 0;
        for (int y = 0; y< h; y++)
            scanf("%s", &(str[y]));
        int startx, starty;
        bool flag = false;
        for (startx = 0; startx <w&& flag == false; )
        {
            for (int j=0; j<h&& flag == false; j++)
                if (str[j][startx] == '#')
                {
                     flag = true;
                }
            if(flag == false)
                startx++;
        }
        flag = false;
        for (starty =0; starty<h && flag == false; )
        {
            for (int j=0; j< w && flag == false; j++)
                if (str[starty][j] == '#')
                    flag = true;
            if (flag == false)
                starty++;
        }
        for (int y = starty; y<h; y++)
        {
            for (int x = startx; x <w; x++)
            {
                if (str[y][x]== '#')
                {
                    Const[i][starNum[i]].x = x-startx;
                    Const[i][starNum[i]].y = y-starty;
                   // printf("const %d star %d x %d y %d\n", i, starNum[i], x, y);
                    starNum[i]++;
                }
            }
        }
    }

    scanf("%d %d", &n, &m);
    for (int i=0; i< n; i++)
       scanf("%s", &(map[i]));
    for (int i=0; i<k; i++)
    {
        if (has(i))
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值