专栏文章

题解:UVA658 这不是bug,而是特性 It's not a Bug, it's a Feature!

UVA658题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@miowd9ws
此快照首次捕获于
2025/12/03 02:14
3 个月前
此快照最后确认于
2025/12/03 02:14
3 个月前
查看原文

思路

在任意时刻,枚举补丁看是否能用当前补丁,如果符合当前补丁使用的状态,就使用补丁进行修补。
记得用二进制表示打补丁之前与打上补丁之后的状态。

代码

CPP
#include<bits/stdc++.h>
using namespace std;
template<typename T>void read(T&x)
{
	x = 0;char c;int sign = 1;
	do { c = getchar(); if(c == '-') sign = -1; }while(!isdigit(c));
	do { x = x * 10 + c - '0'; c = getchar(); }while(isdigit(c));
	x *= sign;
}
const int N = 1 << 20; 
int n,m,s,a[N],b[N],c[N],d[N];
long long dis[N],t[N];

priority_queue<pair<long long,int> > q; 
void SPFA()
{
	memset(dis,0x3f,sizeof dis);
	dis[s] = 0; q.push(make_pair(0,s));
	while(!q.empty())
	{
		int x = q.top().second; q.pop();
		for(int i = 1;i <= m; ++ i)
			if(((x&a[i]) == a[i]) && (x&b[i])==0) // 表示 x 是否能打上补丁i a[i]表示打补丁前有bug的位置 b[i]表示打补丁前没bug的位置 
			{
				int y = (x|c[i])&d[i]; // 表示x打上补丁后的状态 c[i]打补丁后有bug的位置  d[i]打补丁后没bug的位置 
				if(dis[y] > dis[x] + t[i])
				{
					dis[y] = dis[x] + t[i];
					q.push(make_pair(-dis[y],y));
				}
			}
	}
}

int main()
{
	for(int k = 1;;k++)
	{
		read(n); read(m);
		if(n == 0 && m == 0) break; 
		cout << "Product " << k << endl;
		s = (1 << n) - 1; 
		for(int i = 1;i <= m; ++ i)
		{
			string c1,c2;
			cin >> t[i] >> c1 >> c2;
			a[i] = 0; b[i] = 0; c[i] = 0; 
			for(int j = 0;j < n; ++ j)
				if(c1[j] == '+')
					a[i] |= (1 << j);
				else if(c1[j] == '-')
					b[i] |= (1 << j);
			d[i] = s;
			for(int j = 0;j < n; ++ j)
				if(c2[j] == '+')
					c[i] |= (1 << j);
				else if(c2[j] == '-')
					d[i] ^= (1 << j);
		}
		SPFA(); 
		if(dis[0] == 0x3f3f3f3f3f3f3f3f)
			cout << "Bugs cannot be fixed." << endl;
		else cout << "Fastest sequence takes "<< dis[0] << " seconds." << endl;
		cout << endl; 
	 } 
	return 0;
}

评论

1 条评论,欢迎与作者交流。

正在加载评论...