UVa 658 It's not a Bug, it's a Feature!
2015-06-22 15:54
399 查看
It's not a Bug, it's a Feature! |
Input
The input contains several product descriptions. Each description starts with a line containing two integers n and m,the number of bugs and patches, respectively. These values satisfy and .This is followed by m lines describing the m patchesin order. Each line contains an integer, the time in seconds it takes to apply the patch, and two strings of n characterseach.The first of these strings describes the bugs that have to be present or absent before the patch can be applied. The i-th position of that string is a ``+'' if bug bi hasto be present, a ``-'' if bug bi has to be absent, and a `` 0'' if it doesn't matter whether the bug is present or not.The second string describes which bugs are fixed and introduced by the patch. The i-th position of that string is a ``+'' if bug bi is introduced by thepatch, a ``-'' if bug bi is removed by the patch (if it was present), and a ``0'' if bug bi is not affected by the patch (if it was present before, it still is, if it wasn't, is stillisn't).The input is terminated by a description starting with n = m = 0. This test case should not be processed.Output
For each product description first output the number of the product. Then output whether there is a sequence of patches that removes all bugs from a product that has all n bugs.Note that in such a sequence a patch may be used multiple times. If there is such a sequence, output the time taken by the fastest sequence in the format shown in the sample output. If there is no such sequence, output ``Bugs cannot be fixed.''.Print a blank line after each test case.Sample Input
3 3 1 000 00- 1 00- 0-+ 2 0-- -++ 4 1 7 0-0+ ---- 0 0
Sample Output
Product 1 Fastest sequence takes 8 seconds. Product 2 Bugs cannot be fixed.
#include <cstdio>#include <string>#include <queue>#include <cstring>#include <iostream>#include <map>using namespace std;// 节点结构体typedef struct node{int num; // 节点编号int dist; // 从开始节点到该节点的距离bool operator < (const struct node& x) const{return dist > x.dist;}}node;// d[i]记录从开始节点到i结点的距离int d[1050000];//map<int, int> d;/*// 边结构体typedef struct edge{string s; // 起点的格式string t; // 终点的格式int w; // 边的权重}edge;// 记录所有边edge e_array[110];*/char before[110][110], after[110][110];int w[110];int n, m;// 记录节点是否被查看过int visit[1050000];//map<int,int> visit;int main(){int count = 1;// while(cin >> n >> m && !(n == 0 && m == 0))while(scanf("%d%d", &n, &m) == 2 && !(n == 0 && m == 0)){// 初始化int begin = (1<<n)-1;// d = map<int,int>();// visit = map<int,int>();/* memset(d, -1, sizeof(int)*(1<<n));memset(visit, 0, sizeof(int)*(1<<n));*/for(int i = 0; i <= begin; i++){visit[i] = 0;d[i] = -1;}d[begin] = 0;// 读入所有边for(int i = 0; i < m; i++){// cin >> e_array[i].w >> e_array[i].s >> e_array[i].t;scanf("%d %s %s", &w[i], before[i], after[i]);}// 将当前节点加入队列node q;q.num = begin;q.dist = 0;priority_queue<node> my_queue;my_queue.push(q);// 计算该节点到终点的最短路径int ans = -1;while(my_queue.size() > 0){node p = my_queue.top();my_queue.pop();if(visit[p.num] == 1)continue;/* if(visit.find(p.num) != visit.end() && visit[p.num] == 1)continue;*/ visit[p.num] = 1;if(p.num == 0){ans = p.dist;break;}// 更新所有未访问的节点与开始节点的距离/* // 得到该点的二进制表示char s1[25];memset(s1, 0, sizeof(s1));for(int i = 0; i < n; i++){s1[i] = ((p.num & (1<<(n-1-i))) >> (n-1-i)) + '0';}*/ for(int i = 0; i < m; i++){int j;for(j = 0; j < n; j++){/* if(e_array[i].s[j] == '-' && s1[j] == '1')break;else if(e_array[i].s[j] == '+' && s1[j] == '0')break;*//* if(e_array[i].s[j] == '-' && ((p.num & (1<<(n-1-j))) != 0))break;else if(e_array[i].s[j] == '+' && ((p.num & (1<<(n-1-j))) == 0))break;*/if(before[i][j] == '-' && ((p.num & (1<<(n-1-j))) != 0))break;else if(before[i][j] == '+' && ((p.num & (1<<(n-1-j))) == 0))break;}if(j == n){int q = p.num;for(int k = 0; k < n; k++){/*if(e_array[i].t[k] == '0')q = (q<<1) + (s1[k]-'0');else if(e_array[i].t[k] == '-')q = (q<<1);else if(e_array[i].t[k] == '+')q = (q<<1) + 1;*//* if(e_array[i].t[k] == '-')q = (q & ~(1 << (n-1-k)));else if(e_array[i].t[k] == '+')q = (q | (1 << (n-1-k)));*/if(after[i][k] == '-')q = (q & ~(1 << (n-1-k)));else if(after[i][k] == '+')q = (q | (1 << (n-1-k)));}// printf("p: %d q: %d, i: %d\n", p.num, q, i);if( visit[q] == 0// && (d[q] == -1 || d[q] > d[p.num] + e_array[i].w))&& (d[q] == -1 || d[q] > d[p.num] + w[i])){// d[q] = d[p.num] + e_array[i].w;d[q] = d[p.num] + w[i];node next_p;next_p.num = q;next_p.dist = d[q];my_queue.push(next_p);}}}}printf("Product %d\n", count);if(ans == -1)printf("Bugs cannot be fixed.\n\n");elseprintf("Fastest sequence takes %d seconds.\n\n", ans);count++;}return 0;}
题目思路不难,把当前产品状态看作节点,补丁看作边。即寻找从全1状态至全0状态的最短路径。
使用Dijkstra算法,用优先队列框架做,TLE.
一开始以为是d和visit数组开的过大(达到10^6), 改用map仍然TLE.
看了汝佳的代码:https://github.com/aoapc-book/aoapc-bac2nd/blob/master/ch11/UVa658.cpp
把判断边能不能使用改成了位操作。仍然TLE.
把memset换成循环,TLE.
后来把唯一不一样的地方:cin改成scanf, 通过。
数据较大时,cin较scanf慢。
相关文章推荐
- UnitNode API
- InitialWordNode API
- WordNode API
- HMMNode API
- Javascript中的this
- [LeetCode][JavaScript]Basic Calculator II
- 纯css实现多行文本省略号显示
- JSP乱码解决(过虑器EncodingFilter)
- (译)JavaScript内存泄露
- JS关闭窗口或JS关闭页面的几种代码
- 前端bootstrap和jquery使用记录
- 关于CSS背景background属性经典的配置
- sockjs-web实时通信协议
- html小知识
- JQuery处理checkbox的checked属性正确用法
- poj 1543 Perfect Cubes
- jquery 使用$.ajax post方法提交数据
- 《深入理解JavaScript系列》系列技术文章整理收藏
- LABjs(类似于LazyLoad,但它更加方便管理依赖关系)
- 我的THREE.js之旅01