您的位置:首页 > Web前端

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! 
It is a curious fact that consumers buying a new software product generally do not expect the software to be bug-free. Can you imagine buying a car whose steering wheel only turns to the right?Or a CD-player that plays only CDs with country music on them? Probably not. But for software systems it seems to be acceptable if they do not perform as they should do. In fact, many software companies have adopted the habit of sending out patches to fixbugs every few weeks after a new product is released (and even charging money for the patches).Tinyware Inc. is one of those companies. After releasing a new word processing software this summer, they have been producing patches ever since. Only this weekend they have realized a big problem withthe patches they released. While all patches fix some bugs, they often rely on other bugs to be present to be installed. This happens because to fix one bug, the patches exploit the special behavior of the program due to another bug.More formally, the situation looks like this. Tinyware has found a total of n bugs  intheir software. And they have released m patches . To apply patch pi to the software,the bugs  have to be present in the software, and the bugs  mustbe absent (of course  holds). The patch then fixes the bugs  (ifthey have been present) and introduces the new bugs  (where, again, ).Tinyware's problem is a simple one. Given the original version of their software, which contains all the bugs in B, it is possible to apply a sequence of patches to the software which resultsin a bug- free version of the software? And if so, assuming that every patch takes a certain time to apply, how long does the fastest sequence take?

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慢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: