UVA1423Guess (dfs,bfs拓扑排序)
2015-09-24 23:25
501 查看
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36239
题意:给定S( i , j ) , ( i <= j) 的矩阵表示一个数字序列第i个到第j个元素的连续和的符号,‘+’,‘-’,‘0’,求序列的一种可能值。
思路:矩阵中的每个元素都可以看作是序列前缀和之差的结果,若设sum(i)为前i个元素的前缀和,则S( i, j )表示sum(j)- sum(i)的结果的符号,可以从确定关系的两个前缀和间连一条有向边,从小的指向大的(反之亦可),然后进行拓扑排序得到sum(i)的一种大小关系。最后对sum(i)依次赋值,即可得到序列。
敲了两种版本的拓扑排序,dfs 和 bfs两种版本
代码:
dfs版
bfs版
题意:给定S( i , j ) , ( i <= j) 的矩阵表示一个数字序列第i个到第j个元素的连续和的符号,‘+’,‘-’,‘0’,求序列的一种可能值。
思路:矩阵中的每个元素都可以看作是序列前缀和之差的结果,若设sum(i)为前i个元素的前缀和,则S( i, j )表示sum(j)- sum(i)的结果的符号,可以从确定关系的两个前缀和间连一条有向边,从小的指向大的(反之亦可),然后进行拓扑排序得到sum(i)的一种大小关系。最后对sum(i)依次赋值,即可得到序列。
敲了两种版本的拓扑排序,dfs 和 bfs两种版本
代码:
dfs版
#include<bits/stdc++.h> using namespace std; int G[15][15], vis[15], rec[15][15], ans[15], Ans[15]; int len, n; void dfs(int u){ vis[u] = 1; for(int i = 0; i <= n; i++){ if(!vis[i] && G[u][i]) dfs(i); } ans[len--] = u; //记录路径,从后往前记录 } int main(){ int t; scanf("%d", &t); while(t--){ scanf("%d", &n); len = n; memset(G, 0, sizeof(G)); memset(vis, 0, sizeof(vis)); memset(rec, 0, sizeof(rec)); char a; getchar(); for(int i = 1; i <= n; i++){ for(int j = i; j <= n; j++){ scanf("%c", &a); if(a == '+') G[i-1][j] = 1; else if(a == '-') G[j][i-1] = 1; else if(a == '0') rec[i-1][j] = rec[j][i-1] = G[i-1][j] = 1; } } for(int i = 0; i <= n; i++) if(!vis[i]) dfs(i); Ans[ans[0]] = 0; for(int i = 1; i <= n; i++){ // 对找到的前缀和序列赋值 if(rec[ans[i]][ans[i-1]]) Ans[ans[i]] = Ans[ans[i-1]]; else Ans[ans[i]] = Ans[ans[i-1]] + 1; } for(int i = 1; i <= n; i++){ printf("%d%c", Ans[i]-Ans[i-1], i == n?'\n':' '); } } return 0; }
bfs版
#include<bits/stdc++.h> using namespace std; int G[15][15], rec[15], cnt, n, ans[15]; // rec[i]数组记录可能比第i个元素小的序列元素的数量 void bfs(){ queue<int> q; while(!q.empty()) q.pop(); for(int i = 0; i <= n; i++) if(rec[i] == 0) q.push(i); while(!q.empty()){ int sz = q.size(); for(int i = 0; i < sz; i++){ int u = q.front(); q.pop(); ans[u] = cnt; // 对找到的前缀和序列赋值 for(int v = 0; v <= n; v++){ if(G[u][v]){ rec[v]--; if(rec[v] == 0) q.push(v); } } } cnt++; } } int main(){ int t; scanf("%d", &t); while(t--){ cnt = 0; char tmp; scanf("%d", &n); memset(G, 0, sizeof(G)); memset(rec, 0, sizeof(rec)); getchar(); for(int i = 1; i <= n; i++){ for(int j = i; j <= n; j++){ scanf("%c", &tmp); if(tmp == '+') G[i-1][j] = 1, rec[j]++; else if(tmp == '-') G[j][i-1] = 1, rec[i-1]++; } } bfs(); for(int i = 1; i <= n; i++){ printf("%d%c", ans[i]-ans[i-1], i == n ? '\n' : ' '); } } return 0; }
相关文章推荐
- 【 UIImageView图片控件】
- STL系列之三 queue 单向队列
- Flume 1.6.0 User Guide
- android开发步步为营之79:通过源码分析Looper,Handler,MessageQueue之间的关系
- NGUI 3D菜单
- js中return、return true、return false的区别
- ZOJ.2421 Recaman's Sequence【暴力打表】 2015/09/24
- UI一揽子计划 24 (MVC、通知、)
- UI一揽子计划 23 (动画的使用场景、UIView动画、CGAffineTransform2D仿射变换、CALayer、CAAnimation、)
- hdu1159 Common Subsequence (最长公共子串)
- UI Overview
- jquey 92 json.parse json.stringify
- IOS每天15个注意点系列之UI-tableView
- XMPP didReceivePresenceSubscriptionRequest函数不执行解决办法
- HDU - 3732 Ahui Writes Word(多重背包)
- Windows 7 and Ubuntu install issues
- lintcode-Segmemt Tree Build II-439
- 【IOS学习笔记】UITableView隐藏多余分割线
- 【IOS学习笔记】UITableView 点击隐藏键盘 且不影响其他事件
- Java序列化机制中的类版本问题 serialVersionUID的静态字段 含义