• Codeforces 1105D(双层广搜)


    要点

    • 题意:可以拐弯,即哈密顿距离
    • 注意不可以直接一个一个搜,这过程中会把下一轮的标记上,导致同一轮的其它点没能正常完成应有的搜索
    • 因此采用双层广搜,把同一轮先都出队列再的一起搜
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <cctype>
    using namespace std;
    
    const int maxp = 10;
    const int tx[] = {0, 0, -1, 1};
    const int ty[] = {-1, 1, 0, 0};
    
    struct node {
    	int x, y, c;
    	node() {}
    	node(int a, int b, int c):x(a), y(b), c(c) {}
    };
    int n, m, p;
    int pace[maxp];
    char grid[1001][1001];
    
    vector<node> st[maxp];
    queue<node> Q;
    queue<pair<node, int>> q;
    int cnt[maxp];
    
    int main() {
    	scanf("%d %d %d", &n, &m, &p);
    	for (int i = 1; i <= p; i++)
    		scanf("%d", &pace[i]);
    	for (int i = 1; i <= n; i++) {
    		scanf("%s", grid[i] + 1);
    		for (int j = 1; j <= m; j++)
    			if (isdigit(grid[i][j]))
    				st[grid[i][j] - '0'].emplace_back(i, j, grid[i][j] - '0');
    	}
    
    	for (int i = 1; i <= p; i++)
    		for (auto j : st[i])
    			Q.emplace(j);
    	while (!Q.empty()) {
    		auto t = Q.front(); Q.pop();
    
    		for (int dir = 0; dir < 4; dir++) {//本轮第一步
    			int nx = t.x + tx[dir], ny = t.y + ty[dir];
    			if (nx < 1 || nx > n || ny < 1 || ny > m || grid[nx][ny] != '.')	continue;
    			grid[nx][ny] = t.c + '0';
    			q.emplace((node){nx, ny, t.c}, 1);
    		}
    		if (Q.size() && t.c == Q.front().c)	continue;//同一轮的所有人一起扩展
    
    		while (!q.empty()) {//本轮扩展
    			node tmp = q.front().first;
    			int len = q.front().second;
    			q.pop();
    			if (len == pace[tmp.c]) {//本次最外界
    				Q.emplace(tmp); continue;
    			}
    			for (int dir = 0; dir < 4; dir++) {
    				int nx = tmp.x + tx[dir], ny = tmp.y + ty[dir];
    				if (nx < 1 || nx > n || ny < 1 || ny > m || grid[nx][ny] != '.')	continue;
    				grid[nx][ny] = tmp.c + '0';
    				q.emplace((node){nx, ny, tmp.c}, len + 1);
    			}
    		}
    	}
    
    	for (int i = 1; i <= n; i++)
    		for (int j = 1; j <= m; j++)
    			if (isdigit(grid[i][j]))
    				cnt[grid[i][j] - '0']++;
    	for (int i = 1; i <= p; i++)
    		printf("%d ", cnt[i]);
    }
    
  • 相关阅读:
    如何禁用 Azure 虚拟机的日期时间同步
    Java 如何启用 ARM 虚拟机诊断
    File类的源码学习
    Trie树学习
    Hadoop自带Sort例子分析
    java.io.IOException: Illegal partition for 67 (-1)
    Java IO、网络编程、NIO、Netty、Hessian、RPC、RMI的学习路线
    MapReduce中的排序(附代码)
    CAP理论学习
    Harvard数据库课程CS 265: Research Topics in Database Systems
  • 原文地址:https://www.cnblogs.com/AlphaWA/p/11001836.html
Copyright © 2020-2023  润新知