题意:给出一个矩阵迷宫,要求用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的更多相关文章

随机推荐

  1. XMLHttpRequestUtil

    //XMLHttpRequest类 function XMLHTTPRequestUtil() { this.Instance = null; this.GetXMLHttpRequest = fun ...

  2. linux的多媒体 播放 软件版权问题

    linux下基本很多 跟多媒体 相关的软件, 都是有版权的, 都是 第三方软件, 都是closed-resource的 都有版权问题, 因此, 几乎所有的 linux的 发行版 都不会带有 多媒体软件 ...

  3. C/C++使用HTTP协议上传

    上传文件: http://zengrong.net/post/2088.htm #include <stdio.h> #include <string.h> #include ...

  4. ktouch移动端事件库

    最近闲来无事,写了个移动端的事件库,代码贴在下面,大家勿拍. /** @version 1.0.0 @author gangli @deprecated 移动端触摸事件库 */ (function ( ...

  5. spring学习

    http://blog.csdn.net/chjttony/article/details/6301523 http://blog.csdn.net/chjttony/article/details/ ...

  6. HDOJ 4768 Flyer

    二分.... Flyer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  7. Hadoop 面试题之storm 3个

    Hadoop 面试题之八 355.metaq 消息队列 zookeeper 集群 storm集群(包括 zeromq,jzmq,和 storm 本身)就可以完成对商城推荐系统功能吗?还有其他的中间件? ...

  8. xcode7 NSAppTransportSecurity

    在Info.plist中添加  NSAppTransportSecurity 类型  Dictionary Dictionary 下添加  NSAllowsArbitraryLoads 类型 Bool ...

  9. Apache 虚拟主机

    httpd支持的虚拟主机类型包括以下三种 基于域名:为每个虚拟主机使用不同的域名.但其对应的IP使相同的. 基于IP地址:为每个虚拟主机使用不同的域名,切各自对应的IP地址也不相同. 基于端口:这种方 ...

  10. HDU 5384 字典树、AC自动机

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5384 用字典树.AC自动机两种做法都可以做 #include<stdio.h> #includ ...