zoukankan      html  css  js  c++  java
  • hiho1099_constellation

    题目

        一 个NxM(N, M <= 1000)的矩阵形成星空,矩阵中的点有两种字符,'#'代表星星,'.'代表空白,星空中的星星最多5000个;给出K(K<=20)个星图,每 个星图都是HxW(H, W <= 100)的矩阵,矩阵中的点有两种字符,'#'代表星星,'.'代表空白,星图中的星星最多20个。问给出的K个星图在给出的星空中能否找到?

        字符匹配问题,最简单粗暴的就是直接枚举。但是分析一下复杂度,发现直接暴力枚举复杂度为:(1000x1000x100x100x20),显然不行。
        继续分析一下题中给出的数字,“星空中的星星最多5000个,星图中的星星最多20个”,根据这个条件,考虑存储星空和星图中的那些星星的坐标,将数据进行压缩,然后看星图中的星星坐标(可能经过移动)能否从星空中找到。
        这本是一个很好的开始!但之后,我就开始了傻逼模式:试图将星图分别在x方向和y方向上进行平移,然后得到新的星星坐标,再从星空中星星坐标库中 查找是否有移动后的星星坐标,期间还很自以为机智的使用二分查找加快速度。。。。但是,没有发现这样做的时间复杂度为 (1000x1000x20xlog(5000)) 仍然很大。。
        网上看了别人的做法,发现只需要将星空中的每一个星星位置作为星图中星星的起始点(从上到下,左到右遇到的第一个星星位置),然后根据星图中星星 之间的相对位置,找到将星图起始点对应过去之后,星图中星星在星空中的位置,判断该位置处是否为一颗星星。这样,直到在星空中找到一颗星星作为星图中星星 的起始星星,这样对应之后,星图中的所有星星在星空中的位置都有星星对应,就可以判断星空中存在该星图。这样时间复杂度为(5000x20x20)
        这道题提交了十多遍,我屮艸芔茻。。我真是一个大傻逼啊!
        现在反思一下自己当时的几个失误:
    (1)进行第一步简化之后,没有继续分析复杂度,放弃了继续简化的机会;
    (2)简化,存储星空中星星的坐标时,就把星空的整体数据给丢掉了(没有想到存储星空中每个点是什么)。这样在之后查找的时候,用二分,而不是直接判断。。

    实现

    #include<iostream>
    #include<stdio.h>
    #include<algorithm>
    #include<unordered_map>
    #include<list>
    #include<string>
    #include<string.h>
    #include<set>
    #include<queue>
    using namespace std;
    int cons_star_c[25][25];
    int cons_star_r[25][25];
    int cons_width[25];
    int cons_height[25];
    int stars_c[5005];
    int stars_r[5005];
    int cons_star_count[25];
    int stars_total_count;
    int stars_width;
    int stars_height;
    char map[1005][1005];
    
    
    bool findConstellation(int k) {
    	for (int i = 0; i < stars_total_count; i++) {
    		int j = 0;
    		for (; j < cons_star_count[k]; j++) {
    			int col = cons_star_c[k][j] - cons_star_c[k][0] + stars_c[i];
    			int row = cons_star_r[k][j] - cons_star_r[k][0] + stars_r[i];
    			if (!(col >= 0 && col < stars_width && row >= 0 && row < stars_height)) {
    				break;
    			}
    			else if (map[row][col] == '.') {
    				break;
    			}
    		}
    		if (j == cons_star_count[k])
    			return true;
    	}
    	return false;
    }
    int main() {
    	int K, H, W;
    	char symbol;
    	cin >> K;
    	scanf("%d", &K);
    	for (int i = 0; i < K; i++) {
    		cin >> H >> W;		
    		cons_height[i] = H;
    		cons_width[i] = W;
    		int star_count = 0;
    		for (int row = 0; row < H; row++) {
    			for (int col = 0; col < W; col++) {
    				cin >>symbol;
    				if (symbol == '#') {
    					cons_star_r[i][star_count] = row;
    					cons_star_c[i][star_count] = col;
    					star_count++;
    				}
    			}
    		}
    		cons_star_count[i] = star_count;
    	}
    	
    	cin >> H >> W;
    	stars_width = W;
    	stars_height = H;
    	stars_total_count = 0;
    	for (int row = 0; row < H; row++) {
    		for (int col = 0; col < W; col++) {
    			cin >>symbol;
    			map[row][col] = symbol;
    			if (symbol == '#') {
    				stars_r[stars_total_count] = row;
    				stars_c[stars_total_count] = col;
    				stars_total_count++;
    			}
    		}
    	}
    	for (int i = 0; i < K; i++) {
    		if (findConstellation(i))
    			printf("Yes
    ");
    		else
    			printf("No
    ");
    	}
    	return 0;
    }
    
  • 相关阅读:
    【转】一个java处理JSON格式数据的通用类
    Oracle数据类型Clob读取
    【网摘】Ibatis调用存储过程
    jQuery实现页面模块拖拽与模块自定义效果.rar
    jspSmartUpload上传下载全攻略
    【转】JSON 入门指南
    【摘选自江苏移动网上营业厅】JS实现无间断向上滚动marquee
    Oracle用户解锁
    js 蒙版进度条(图片)
    java文件夹遍历
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/5600202.html
Copyright © 2011-2022 走看看