hihocoder #1099 : Constellations

时间限制: 10000ms
单点时限: 1000ms
内存限制: 256MB

描述

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.

样例输入
3
5 5
#....
.....
...#.
.....
.#...
5 5
....#
.....
.....
#....
....#
5 6
.....#
......
#.....
......
....#.
10 10
.......#..
..........
..#.......
..........
......#...
..........
..........
..#.......
......#...
..........
样例输出
No
Yes
Yes
最初的错误想法是从sky的那个矩阵的(0,0)端点开始依次与上面的小picture做比较。
小picture的第一行与sky的(0,0)开始,长度为picture一行的长度做比较,如果一致,则将picture第二行与sky(1,0)比较,这样一直纵向比较下去,直到picture的第n行与sky(n,0)不相等为止。
对于不相等的情况,恢复到之前纵向比较的位置,并向右移一位,与picture第一行做比较。

保证以后再也不贴错误代码了。。。好不容易写出这么大段,舍不得%>_<%
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
	int k;
	cin >> k;
	vector<vector<string>>con;
	while (k--)
	{
		vector<string>tmp;
		int w, h;
		cin >> w >> h;
		char a;
		for (int i = 0; i < w; i++)
		{
			string s;
			cin >> s;
			tmp.push_back(s);
		}
		con.push_back(tmp);
	}
	int w1, h1;
	cin >> w1 >> h1;
	char b;
	vector<string>finc;
	vector<vector<int>>visit;
	for (int i = 0; i < w1; i++)
	{
		string ss;
		cin >> ss;
		finc.push_back(ss);
	}
	int flag;
	for (int i1 = 0; i1 < con.size(); i1++)
	{
		visit.clear();
		for (int i = 0; i < w1; i++)
		{
			vector<int>v1;
			for (int j = 0; j < h1; j++)
			{
				v1.push_back(0);
			}
			visit.push_back(v1);
		}
		vector<string>tmp = con[i1];
		int row = 0;
		int count_row = -1;
		flag = 0;
		for (int i = 0;i < finc.size()-tmp.size()+1; i++)
		{
			if (i >= finc.size())
				break;

			for (int j = 0; j < w1 - tmp[0].size() + 1;)
			{
				if (i >= finc.size())
					break;
				//cout << "i,j " << i << " " << j << endl;

				if (visit[i][j] == 0)
				{
					if (tmp[row] == finc[i].substr(j, tmp[row].size()))  //怎么可以直接比较呢
					{
						visit[i][j] = 1;
						if (row == 0)
						{
							//cout << "row=0, i= " << i << endl;
							count_row = i;            //记录纵向比较时最初的行数
						}
						i++;
						row++;
						if (row == tmp.size())           //比较到最后一行也相等的则输出YES
						{
							flag = 1;
							break;
						}
					}
					else
					{
						visit[i][j] = -1;
						j++;
						row = 0;
						if (count_row != -1)
						{
							i = count_row;     //恢复纵向比较最初的行数
							count_row = -1;
						}
						if (j == finc[0].size() - tmp[0].size() + 1)
						{
							j = 0;
							i++;
						}
					}
				}
				else
					j++;
			}
			
			if (flag == 1)
			{
				cout << "Yes" << endl;
				break;
			}
		}
		if (flag!=1)
			cout << "No" << endl;
	}
	system("pause");
	return 0;
}

忽视了一个重大问题好么!!!!那些星座之间有可能重叠的好么,不仅仅是共用某个星星。所以这样依次比较string是否完全相等根本就是错误的好么!!!

然后修改了两个字符串比较的函数。
bool star_com(string a, string b)
{
	int len = a.size();
	for (int i = 0; i < len; i++)
	{
		if (a[i] == '#')
		{
			if (b[i] != '#')
				return false;
		}
	}
	return true;
}

稍微改了一下变成这个样子
#include <iostream>
#include <string>
#include <vector>
using namespace std;

bool star_com(string a, string b)
{
	int len = a.size();
	for (int i = 0; i < len; i++)
	{
		if (a[i] == '#')
		{
			if (b[i] != '#')
				return false;
		}
	}
	return true;
}

int main()
{
	int k;
	cin >> k;
	vector<vector<string>>con;
	while (k--)
	{
		vector<string>tmp;
		int w, h;
		cin >> w >> h;
		char a;
		for (int i = 0; i < w; i++)
		{
			string s;
			cin >> s;
			tmp.push_back(s);
		}
		con.push_back(tmp);
	}
	int w1, h1;
	cin >> w1 >> h1;
	char b;
	vector<string>finc;
	for (int i = 0; i < w1; i++)
	{
		string ss;
		cin >> ss;
		finc.push_back(ss);
	}
	int flag;
	for (int i1 = 0; i1 < con.size(); i1++)
	{
		vector<string>tmp = con[i1];
		int row = 0;
		int count_row = -1;
		flag = 0;
		for (int i = 0; i < finc.size() - tmp.size() + 1; i++)
		{
			if (i >= finc.size())
				break;

			for (int j = 0; j < w1 - tmp[0].size() + 1;)
			{
				if (i >= finc.size())
					break;
				if (star_com(tmp[row], finc[i].substr(j, tmp[row].size())))
				{
					if (row == 0)
						count_row = i;
					i++;
					row++;
					if (row == tmp.size())
					{
						flag = 1;
						break;
					}
				}
				else
				{
					j++;
					row = 0;
					if (count_row != -1)
					{
						i = count_row;
						count_row = -1;
					}
					if (j == finc[0].size() - tmp[0].size() + 1)
					{
						j = 0;
						i++;
					}
				}
			}

			if (flag == 1)
			{
				cout << "Yes" << endl;
				break;
			}
		}
		if (flag != 1)
			cout << "No" << endl;
	}
	system("pause");
	return 0;
}
很好,现在变超时了。。。。(╯‵□′)╯︵┻━┻      能否告诉我怎样优化!!!
看来要全部重写了,这就是题目条件利用不充分的后果。

看里面的数据都不大,对前面的小图保存于第一个星星的相对位置。然后在便利sky时,对里面的每个点都依次视为第一个小图的第一星星,然后对比其他星星的吻合情况。

#include <iostream>
using namespace std;

struct point
{
	int x, y;
};

struct con
{
	int total_p;    //统计小图中星星的数量
	point p[20];
}conl[20];

char finc[1000][1000];

int main()
{
	int k;
	cin >> k;
	int count = 0;
	for (int K = 0; K < k;K++)
	{
		int w, h;
		cin >> w >> h;
		char a;
		conl[K].total_p = 0;
		int xx,yy;
		for (int i = 0; i < w; i++)
		{
			for (int j = 0; j < h; j++)
			{
				cin >> a;
				if (a == '#')
				{
					if (conl[K].total_p == 0)
					{
						xx = i;
						yy = j;
						conl[K].total_p = 1;
					}
					else
					{
						conl[K].p[conl[K].total_p].x = i - xx;
						conl[K].p[conl[K].total_p++].y = j - yy;     //存储相对位置
					}
				}
			}
		}
	}
	int w1, h1;
	cin >> w1 >> h1;
	for (int i = 0; i < w1; i++)
	{
		for (int j = 0; j < h1; j++)
			cin >> finc[i][j];
	}

	for (int K = 0; K< k; K++)
	{
		int f2 = -1;
		for (int i = 0; i < w1&&f2!=0; i++)
		{
			for (int j = 0; j < h1&&f2 != 0; j++)
			{
				if (finc[i][j] == '#')
				{
					int flag = 1;
					for (int m = 0; m < conl[K].total_p; m++)
					{
						int xx = conl[K].p[m].x + i;
						int yy = conl[K].p[m].y + j;
						if (finc[xx][yy] != '#' || xx >= w1 || yy >= h1)
						{
							flag = 0;
							break;
						}
					}
					if (flag == 1)
					{
						f2 = 0;
					}
				}
			}
		}
		if (f2 == 0)
			cout << "Yes" << endl;
		else
			cout << "No" << endl;
	}
	system("pause");
	return 0;
}

终于ac了~~o(>_<)o ~~感觉自己弱爆了





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值