ACM/ICPC 之 拓扑排序+DFS(POJ1128(ZOJ1083)-POJ1270)
两道经典的同类型拓扑排序+DFS问题,第二题较第一题简单,其中的难点在于字典序输出+建立单向无环图,另外理解题意是最难的难点,没有之一...
POJ1128(ZOJ1083)-Frame Stacking
题意:每个图片由同一字母组成的边框表示,每个图片的字母都不同;
在一个最多30*30的区域放置这些图片,问底层向顶层叠加的图片次序,多选时按字典序输出
注:每个图片的四边都会有字符显示,其中顶点显示两边。
题解:题意的理解是难点,题目对图片的范围确定说得有点含糊不清,博主一开始就被出现的五张图片的样例迷惑,理解重心放错了。题目最需要理解的是下方的三句话。
第一句和数据范围就确定了图片尺寸;
第二句话提示读者应该考虑记录对角线上的两个顶点,以此记录该图片的位置和尺寸;
第三句话确定了图片的数量及可以标明该图片的key值(字母)
最后要注意Input中有多组样例,而Ouput中的多组次序需要按照字典序输出。
理清题意后:接下来的工作就是先用两个顶点确立图片的位置和尺寸;
接着利用各图片的位置和尺寸确定覆盖关系建立单向无环图;
最后利用DFS的回溯完成字典序的拓扑排序即可。
//叠图片-拓扑排序+DFS
//每个图片由同一字母组成的边框表示,每个图片的字母都不同
//在一个最多30*30的区域放置这些图片,问底层向顶层叠加的图片次序,多选时按字典序输出
//注:每个图片的四边都至少会有一个字符显示
//Time:0Ms Memory:180K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std; #define MAXN 31 //地图长宽
#define MAXL 26 //字母 struct Coordinate{
int x, y;
}lt[MAXL], rb[MAXL]; //left_top - right_bottom struct Letter {
vector<int> covered;
int in; //in_degree
bool exist;
}let[MAXL]; int row, col;
int total; //字母个数
char ans[MAXL+];
char board[MAXN][MAXN]; void dfs(int len)
{
if (len == total)
{
ans[len] = '\0';
printf("%s\n", ans);
return;
} for (int i = ; i < MAXL; i++)
{
if (!let[i].exist) continue;
if (let[i].in == )
{
ans[len] = i + 'A';
let[i].in--;
for (int j = ; j < let[i].covered.size(); j++)
let[let[i].covered[j]].in--;
dfs(len + );
for (int j = ; j < let[i].covered.size(); j++)
let[let[i].covered[j]].in++;
let[i].in++;
}
} } int main()
{
while (scanf("%d%d", &row, &col) != EOF)
{
total = ;
memset(let, , sizeof(let));
memset(lt, 0x3f, sizeof(lt));
memset(rb, -, sizeof(rb));
//Input and Init
for (int i = ; i < row; i++)
{
scanf("%s", board[i]);
for (int j = ; j < col; j++)
{
if (board[i][j] == '.') continue;
int t = board[i][j] - 'A';
if (!let[t].exist)
let[t].exist = ++total;
lt[t].x = min(lt[t].x, i);
lt[t].y = min(lt[t].y, j);
rb[t].x = max(rb[t].x, i);
rb[t].y = max(rb[t].y, j);
}
} //get_Map
for (int k = ; k < MAXL; k++)
{
if (!let[k].exist) continue;
for (int i = lt[k].x; i <= rb[k].x; i++)
for (int j = lt[k].y; j <= rb[k].y; j++)
{
if (i > lt[k].x && i < rb[k].x && j == lt[k].y + )
j = rb[k].y;
int cur = board[i][j] - 'A';
if (cur == k) continue;
let[k].covered.push_back(cur);
let[cur].in++;
}
} //Topology and Output
dfs();
} return ;
}
POJ1270-Following Orders
本题相当于POJ1128的同类改编题型,相比1128简单。
题意:给定第一行的小写字母,第二行每两个字母描述其约束关系,例如x y 即 x<y,求可以得到的所有有序序列。
题解:这个题目的Input也是让人很醉啊,为了循环接受一行字符,需要使用读取到'\n'才停止的函数。
可以实现的类似的函数有gets,fgets,sscanf;getchar(循环接受单字符);string的getline和cin的getline及get等等
为了方便书写和之后的字符处理,折中选取了cin的getline函数
cin.getline(str,MAX,'\n'):读入最多MAX大的字符串存入str,直到'\n'停止(可以不需要第三个参数)
之后的处理和POJ1128的题解一致,依旧是构图+拓扑排序+DFS,不再累述。
//有序序列-拓扑排序+DFS
//一个难点在于输入,如果使用C语言的gets或者fgets总觉得不好处理
// 于是利用了cin的getline函数,会将'\n'转换成'\0',利于处理
//另一个难点在于字典序输出,需要利用到DFS的回溯
//其余的操作与拓扑排序相同
//Time:0Ms Memory:208K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std; #define MAX 50 struct Letter {
vector<int> bigger;
int in; //in_degree
bool exist;
}let[]; int total;
char ans[MAX]; void dfs(int len)
{
if (len == total)
{
ans[len] = '\0';
printf("%s\n", ans);
return;
} for (int i = ; i < ; i++)
{
if (!let[i].exist || let[i].in) continue;
let[i].in--;
for (unsigned j = ; j < let[i].bigger.size(); j++)
let[let[i].bigger[j]].in--;
ans[len] = i + 'a';
dfs(len + );
for (unsigned j = ; j < let[i].bigger.size(); j++)
let[let[i].bigger[j]].in++;
let[i].in++;
}
} int main()
{
char str[MAX];
while (cin.getline(str, MAX, '\n'))
{
total = ;
memset(let, , sizeof(let));
int len = strlen(str);
for (int i = ; i < len; i += )
if(!let[str[i] - 'a'].exist)
let[str[i] - 'a'].exist = ++total; cin.getline(str, MAX, '\n');
len = strlen(str);
for (int i = ; i < len; i += )
{
int small = str[i] - 'a';
int big = str[i + ] - 'a';
let[small].bigger.push_back(big);
let[big].in++;
} dfs();
printf("\n");
} return ;
}
ACM/ICPC 之 拓扑排序+DFS(POJ1128(ZOJ1083)-POJ1270)的更多相关文章
- ACM/ICPC 之 拓扑排序-反向(POJ3687)
难点依旧是题意....需要反向构图+去重+看题 POJ3687-Labeling Balls 题意:1-N编号的球,输出满足给定约束的按原编号排列的重量序列,如果有多组答案,则输出编号最小的Ball重 ...
- ACM/ICPC 之 拓扑排序范例(POJ1094-POJ2585)
两道拓扑排序问题的范例,用拓扑排序解决的实质是一个单向关系问题 POJ1094(ZOJ1060)-Sortng It All Out 题意简单,但需要考虑的地方很多,因此很容易将code写繁琐了,会给 ...
- 拓扑排序+DFS(POJ1270)
[日后练手](非解题) 拓扑排序+DFS(POJ1270) #include<stdio.h> #include<iostream> #include<cstdio> ...
- POJ1128 Frame Stacking(拓扑排序+dfs)题解
Description Consider the following 5 picture frames placed on an 9 x 8 array. ........ ........ ... ...
- 拓扑排序-DFS
拓扑排序的DFS算法 输入:一个有向图 输出:顶点的拓扑序列 具体流程: (1) 调用DFS算法计算每一个顶点v的遍历完成时间f[v] (2) 当一个顶点完成遍历时,将该顶点放到一个链表的最前面 (3 ...
- Ordering Tasks(拓扑排序+dfs)
Ordering Tasks John has n tasks to do. Unfortunately, the tasks are not independent and the executio ...
- HDU 5438 拓扑排序+DFS
Ponds Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Sub ...
- poj1270Following Orders(拓扑排序+dfs回溯)
题目链接: 啊哈哈.点我点我 题意是: 第一列给出全部的字母数,第二列给出一些先后顺序. 然后按字典序最小的方式输出全部的可能性.. . 思路: 整体来说是拓扑排序.可是又非常多细节要考虑.首先要按字 ...
- Codeforces Round #292 (Div. 2) D. Drazil and Tiles [拓扑排序 dfs]
传送门 D. Drazil and Tiles time limit per test 2 seconds memory limit per test 256 megabytes Drazil cre ...
随机推荐
- JQuery-EasyUI与EXTjs有什么区别?
一.ExtJS1.ExtJS可以用来开发RIA也即富客户端的AJAX应用,是一个用javascript写的,主要用于创建前端用户界面,是一个与后台技术无关的前端ajax框架.因此,可以把ExtJS用在 ...
- Kafka Producer相关代码分析【转】
来源:https://www.zybuluo.com/jewes/note/63925 @jewes 2015-01-17 20:36 字数 1967 阅读 1093 Kafka Producer相关 ...
- struts2上传文件添加进度条
给文件上传添加进度条,整了两天终于成功了. 想要添加一个上传的进度条,通过分析,应该是需要不断的去访问服务器,询问上传文件的大小.通过已上传文件的大小, 和上传文件的总长度来评估上传的进度. 实现监听 ...
- default配置
log_format main '$remote_addr - $remote_user [$time_local] $request ' '"$status" $body_byt ...
- 深入分析,理解jQuery.Deferred源码
前言: 如果你对jQuery.Callback回调对象不了解,或者只掌握其方法,但是没有通过阅读源码理解,可以先阅读 前一章jQuery.Callbacks源码解读二,因为只有完全理解jQuery.C ...
- java 练手 Fibonacci数
Problem B Fibonacci数 时间限制:3000 ms | 内存限制:65535 KB 描述 无穷数列1,1,2,3,5,8,13,21,34,55...称为Fibonacci数列 ...
- 2015baidu复赛2 连接的管道(mst && 优先队列prim)
连接的管道 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- 如何在CentOS 6.5上安装EPEL 源
EPEL 是什么? EPEL (Extra Packages for Enterprise Linux,企业版Linux的额外软件包) 是Fedora小组维护的一个软件仓库项目,为RHEL/CentO ...
- ajax验证登录注册
<form id="form1" onsubmit="return false;"> <table id="login-table& ...
- maven工程通过命令打包
dos下cd到pom.xml所在的目录,输入maven命令:mvn clean package,回车即可. 会打成一个.war包在target文件夹下.