cf515d
题意:给出一个矩阵迷宫,要求用1×2的积木填满空白区域,问解法是否唯一,如果无解或者多解均输出“Not unique"。
分析:广搜。看似二分图匹配但实际上不是。
我们认为每个点和上下左右四个点连接(只考虑空白的点)。先把度为1的点全部入队。
每次弹出一个点a,把那个唯一与它链接的点b与a配对。切断b的所有其他边,观察是否有点的度变为1,将这些点入队。
如此循环直到队列为空。如果仍有空白点未覆盖则必然not unique。因为剩下的点的度均大于1(如果有0的那就无解),所以一定有环存在。
环上只要把原来的配对依次串位一格则又是一种方法。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; #define D(x) const int MAX_N = (int)(2e3) + ; struct Point
{
int x, y;
Point()
{}
Point(int x, int y):x(x), y(y)
{}
Point operator + (const Point &a)
{
return Point(x + a.x, y + a.y);
}
}; Point dir[] = {Point(, ), Point(, ), Point(-, ), Point(, -),
};
int row_num, col_num;
char grid[MAX_N][MAX_N]; bool vis[MAX_N][MAX_N];
Point match[MAX_N][MAX_N]; bool out(Point a)
{
return a.x < || a.y < || a.x >= row_num || a.y >= col_num;
} bool minus_one(Point a)
{
return a.x == - && a.y == -;
} void draw(Point a, char ch)
{
grid[a.x][a.y] = ch;
} void draw(Point a, Point b)
{
if (a.x > b.x || a.y > b.y)
swap(a, b);
if (a.x == b.x)
{
draw(a, '<');
draw(b, '>');
}else
{
draw(a, '^');
draw(b, 'v');
}
} void output()
{
for (int i = ; i < row_num; i++)
puts(grid[i]);
} int get_degree(Point u)
{
int ret = ;
for (int i = ; i < ; i++)
{
Point v = u + dir[i];
if (out(v) || grid[v.x][v.y] != '.')
continue;
ret++;
}
return ret;
} bool not_unique()
{
queue<Point> q;
for (int i = ; i < row_num; i++)
{
for (int j = ; j < col_num; j++)
{
if (get_degree(Point(i, j)) == )
{
q.push(Point(i, j));
}
}
} while (!q.empty())
{
Point u = q.front();
q.pop();
if (grid[u.x][u.y] != '.')
continue;
D(printf("u %d %d\n", u.x, u.y));
Point v;
for (int i = ; i < ; i++)
{
v = u + dir[i];
if (out(v) || grid[v.x][v.y] != '.')
continue;
draw(u, v);
break;
}
u = v;
for (int i = ; i < ; i++)
{
v = u + dir[i];
if (out(v) || grid[v.x][v.y] != '.')
continue;
if (get_degree(v) == )
{
q.push(v);
}
}
} for (int i = ; i < row_num; i++)
{
for (int j = ; j < col_num; j++)
{
if (grid[i][j] == '.')
{
return true;
}
}
}
return false;
} int main()
{
scanf("%d%d", &row_num, &col_num);
for (int i = ; i < row_num; i++)
{
scanf("%s", grid[i]);
} if (not_unique())
{
puts("Not unique");
return ;
} output();
return ;
}
cf515d的更多相关文章
随机推荐
- XMLHttpRequestUtil
//XMLHttpRequest类 function XMLHTTPRequestUtil() { this.Instance = null; this.GetXMLHttpRequest = fun ...
- linux的多媒体 播放 软件版权问题
linux下基本很多 跟多媒体 相关的软件, 都是有版权的, 都是 第三方软件, 都是closed-resource的 都有版权问题, 因此, 几乎所有的 linux的 发行版 都不会带有 多媒体软件 ...
- C/C++使用HTTP协议上传
上传文件: http://zengrong.net/post/2088.htm #include <stdio.h> #include <string.h> #include ...
- ktouch移动端事件库
最近闲来无事,写了个移动端的事件库,代码贴在下面,大家勿拍. /** @version 1.0.0 @author gangli @deprecated 移动端触摸事件库 */ (function ( ...
- spring学习
http://blog.csdn.net/chjttony/article/details/6301523 http://blog.csdn.net/chjttony/article/details/ ...
- HDOJ 4768 Flyer
二分.... Flyer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- Hadoop 面试题之storm 3个
Hadoop 面试题之八 355.metaq 消息队列 zookeeper 集群 storm集群(包括 zeromq,jzmq,和 storm 本身)就可以完成对商城推荐系统功能吗?还有其他的中间件? ...
- xcode7 NSAppTransportSecurity
在Info.plist中添加 NSAppTransportSecurity 类型 Dictionary Dictionary 下添加 NSAllowsArbitraryLoads 类型 Bool ...
- Apache 虚拟主机
httpd支持的虚拟主机类型包括以下三种 基于域名:为每个虚拟主机使用不同的域名.但其对应的IP使相同的. 基于IP地址:为每个虚拟主机使用不同的域名,切各自对应的IP地址也不相同. 基于端口:这种方 ...
- HDU 5384 字典树、AC自动机
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5384 用字典树.AC自动机两种做法都可以做 #include<stdio.h> #includ ...