题意:给出一个矩阵迷宫,要求用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 ;
}

最新文章

  1. iOS 多个播放器同时播放,双击全屏,单击退出全屏
  2. icon fonts
  3. linux 启动weblogic的某服务报错
  4. i++; 与 ++i;的内部区别。
  5. MySQL行级锁、表级锁、页级锁详细介绍
  6. TextView 为部分文字添加下划线,并实现单击事件
  7. ipc$爆破密码
  8. Minigui开发之遥控控制逻辑算法
  9. Photoshop安装
  10. C. Kyoya and Colored Balls(Codeforces Round #309 (Div. 2))
  11. Drying POJ - 3104
  12. 剑指架构师系列-持续集成之Maven实现项目的编译、发布和部署
  13. sxoi爆炸祭
  14. C++生成静态库
  15. django,flask接口初试
  16. 09 Go 1.9 Release Notes
  17. Calendar获取当天的初始时间,当月的初始时间,当年的初始时间
  18. windows下安装mysql5.6
  19. HttpURLConnection如何添加请求头?
  20. Java编程思想 4th 第1章 对象导论

热门文章

  1. 自定义layout中需要重写的方法
  2. linux shell中判断bash脚本输入的参数个数
  3. HDU 2014
  4. jquery选择器(二)-层次选择器
  5. 重读C#委托、事件有感
  6. php 通过curl post发送json数据实例
  7. Centos7下搭建LAMP平台环境
  8. Sql统计一个字符串在另一个字符串出现的次数的函数-fnQueryCharCountFromString
  9. DAY2 raw_input() 与 input() Python
  10. 服务器&amp;域名那些事儿