当前位置: 首页 > news >正文

UVa 658 It‘s Not a Bug It‘s a Feature

题目描述

某软件公司发布了若干补丁,每个补丁用于修复某些bug\texttt{bug}bug,但可能依赖其他bug\texttt{bug}bug的存在或不存在,并且可能会引入新的bug\texttt{bug}bug。给定初始状态(所有nnnbug\texttt{bug}bug均存在),每个补丁具有应用时间。问是否存在一系列补丁(可重复使用)将软件变为无bug\texttt{bug}bug状态,并求最少总时间。

每个补丁由两个长度为nnn的字符串描述:

  • 第一个字符串描述补丁应用的前提条件:'+'表示该bug\texttt{bug}bug必须存在,'-'表示该bug\texttt{bug}bug必须不存在,'0'表示无关紧要。
  • 第二个字符串描述补丁的效果:'+'表示引入该bug\texttt{bug}bug'-'表示修复该bug\texttt{bug}bug(若存在),'0'表示不影响。

输入格式

多组数据。每组数据第一行为两个整数nnnmmm1≤n≤201 \le n \le 201n201≤m≤1001 \le m \le 1001m100),表示 bug 数量和补丁数量。接下来mmm行,每行包含一个整数ttt(补丁应用时间)和两个长度为nnn的字符串(条件串和效果串)。输入以0 0结束。

输出格式

对于每组数据,输出两行:第一行为Product X:,其中XXX为产品编号(从111开始)。第二行若存在方案,输出Fastest sequence takes T seconds.,其中TTT为最少时间;否则输出Bugs cannot be fixed.。每组输出后跟一个空行。

样例

输入

3 3 1 000 00- 1 00- 0-+ 2 0-- -+ 4 1 7 0- 0+-- 0 0

输出

Product 1 Fastest sequence takes 8 seconds. Product 2 Bugs cannot be fixed.

题目分析

本题将软件状态建模为nnn位二进制数,第iii位为111表示bug\texttt{bug}bugiii存在。初始状态为(1<<n)-1,目标状态为000。每个补丁相当于从当前状态到新状态的有向边,边权为补丁时间。应用补丁时需要满足条件:对于条件串中的每位,若为'+',则当前状态对应位必须为111;若为'-',则必须为000;若为'0',则任意。满足条件后,根据效果串更新状态:若为'-',则将该位清000;若为'+',则将该位置111;若为'0',则不变。

由于nnn最大202020,状态数为220≈1062^{20} \approx 10^6220106,节点数可接受。使用Moore-Dijkstra\texttt{Moore-Dijkstra}Moore-Dijkstra算法求从初始状态到目标状态的最短路。由于边权非负,Moore-Dijkstra\texttt{Moore-Dijkstra}Moore-Dijkstra正确且高效。每个状态扩展时,遍历mmm个补丁,检查条件并生成后继状态。总时间复杂度O(2n⋅m)O(2^n \cdot m)O(2nm),在n=20n=20n=20m=100m=100m=100时约为10810^8108,可接受(实际运行时间0.9200.9200.920秒)。

解题思路

  1. 状态表示:用整数state表示nnn位二进制数,表示bug\texttt{bug}bug状态。
  2. 补丁结构:存储时间weight、条件串s1、效果串s2
  3. 条件检查:对每个补丁,检查当前状态u是否满足s1的所有位:
    • s1[j] == '+'bit == 0,则不满足。
    • s1[j] == '-'bit != 0,则不满足。
    • s1[j] == '0',忽略。
  4. 状态转移:若条件满足,则根据s2生成新状态v
    • s2[j] == '-',则将对应位清000
    • s2[j] == '+',则将对应位置111
    • s2[j] == '0',不变。
  5. Moore-Dijkstra\texttt{Moore-Dijkstra}Moore-Dijkstra:从初始状态(1<<n)-1开始,优先队列按当前距离排序。每次取出距离最小的状态,生成所有后继,若新距离更小则更新入队。终止条件:目标状态000被弹出,或队列为空。
  6. 输出:若dist[0]为无穷大,则输出"Bugs cannot be fixed.",否则输出最短时间。

复杂度分析

  • 状态数V=2nV = 2^nV=2n,边数最多V⋅mV \cdot mVm
  • Moore-Dijkstra\texttt{Moore-Dijkstra}Moore-Dijkstra使用优先队列,时间复杂度O((V+E)log⁡V)O((V + E) \log V)O((V+E)logV),其中EEE为实际生成的边数,最坏O(2n⋅m)O(2^n \cdot m)O(2nm)
  • 对于n=20n=20n=20V≈106V \approx 10^6V106E≈108E \approx 10^8E108,但实际可达状态较少,运行时间可接受。

代码实现

// It's Not a Bug It's a Feature// UVa ID: 658// Verdict: Accepted// Submission Date: 2018-05-22// UVa Run Time: 0.920s//// 版权所有(C)2018,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;constintMAXN=(1<<20),INF=0x3f3f3f3f;structrule{intweight;string s1,s2;}rules[128];structedge{intto,weight;edge(intto=0,intweight=0):to(to),weight(weight){}booloperator<(constedge&e)const{returnweight>e.weight;}};intn,m,dist[MAXN];vector<edge>getNext(intu){vector<edge>next;for(inti=0;i<m;i++){boolmatched=true;for(intj=0;j<n;j++){intbit=(1<<(n-j-1))&u;if((bit&&rules[i].s1[j]=='-')||(!bit&&rules[i].s1[j]=='+')){matched=false;break;}}if(matched){intv=u;for(intj=0;j<n;j++){if(rules[i].s2[j]=='-')v&=(~(1<<(n-j-1)));if(rules[i].s2[j]=='+')v|=(1<<(n-j-1));}next.push_back(edge(v,rules[i].weight));}}returnnext;}voidmooreDijkstra(){for(inti=0;i<(1<<n);i++)dist[i]=INF;intu=(1<<n)-1;dist[u]=0;priority_queue<edge>q;q.push(edge(u,dist[u]));while(!q.empty()){edge v=q.top();q.pop();for(autoe:getNext(v.to))if(dist[e.to]>dist[v.to]+e.weight){dist[e.to]=dist[v.to]+e.weight;q.push(edge(e.to,dist[e.to]));}}}intmain(){cin.tie(0),cout.tie(0),ios::sync_with_stdio(false);intcases=0;intweight;string s1,s2;while(cin>>n>>m){if(n==0)break;cout<<"Product "<<++cases<<'\n';for(inti=0;i<m;i++){cin>>weight>>s1>>s2;rules[i]=rule{weight,s1,s2};}mooreDijkstra();if(dist[0]==INF)cout<<"Bugs cannot be fixed.\n\n";elsecout<<"Fastest sequence takes "<<dist[0]<<" seconds.\n\n";}return0;}

总结

本题将Moore-Dijkstra\texttt{Moore-Dijkstra}Moore-Dijkstra状态建模为二进制数,将补丁转化为有向边,利用Moore-Dijkstra\texttt{Moore-Dijkstra}Moore-Dijkstra算法求解最短路径。关键点包括:

  • 正确实现状态转移和条件检查。
  • 使用位运算高效操作状态。
  • 注意输出格式,每组后跟空行。
  • 优化:由于边权非负,Moore-Dijkstra\texttt{Moore-Dijkstra}Moore-Dijkstra适用;也可使用SPFA\texttt{SPFA}SPFA,但Moore-Dijkstra\texttt{Moore-Dijkstra}Moore-Dijkstra更稳定。

该解法是状态空间搜索的典型应用,适用于n≤20n \le 20n20的中等规模问题。

http://www.jsqmd.com/news/1173689/

相关文章:

  • 锂离子电池组电压平衡与保护系统设计
  • 2026淮南潘集中考100-300分无缘普高!淮南家长别焦虑,淮南这所公办中专是最优出路 - 小张zc
  • macOS Git 安装方案对比:官方PKG、Homebrew、Xcode CLI 3种方式实测
  • 如何在Word中一键安装APA第7版参考文献格式:跨平台终极指南
  • VC++ Win32 API实现AVI视频播放器:从VFW原理到双缓冲渲染实战
  • 如何使用OSPerformance:3分钟快速上手操作系统性能分析
  • Git 分支管理策略对比:Git Flow vs GitHub Flow vs GitLab Flow 的 5 个核心差异
  • 别乱卖包!重庆藏着能给稀有皮包溢价的回收实体店大盘点 - 奢侈品回收中心
  • 0基础转行网络安全真的好就业吗?零基础入门到精通看完这篇就足够了~
  • 深度拆解Atmosphère:三步打造你的Switch终极自定义固件系统
  • 潍坊GEO优化公司供应商
  • 现代C++高效开发实战:从环境配置到性能优化的核心精要
  • Wireshark 4.6.6 网络排错实战:3步定位HTTP 500错误与DNS解析超时
  • 长三角硬科技企业海外公司注册服务 - 中媒介
  • EMC预合规测试方案:5万元预算搭建实验室与Tektronix RSA500实测对比
  • 遗传算法工程实践:从早熟收敛到生产级配置的实战指南
  • Unity XR Interaction Toolkit实战:5分钟集成Pico VR手柄移动、抓取与瞬移
  • NS模拟器管理终极指南:NsEmuTools深度解析与实战应用
  • 2026年7月沈阳大疆售后设备深度养护方案|延长设备使用寿命全攻略 - 大品牌推荐
  • DHCP 主机名冲突排查:2个客户端同名导致 dnsmasq 记录覆盖分析
  • 如何用多层架构设计打造稳定的自定义固件系统?
  • 医疗信创标杆:一院两区全栈国产化改造方案与数据库应用、代码实践
  • 山西太原热门的GEO公司有哪些
  • ChatGPT生成YAML配置:为什么87%的工程师在CI/CD中踩坑?附12条校验规则与自动化验证脚本
  • GitHub开源项目日报 · 2026年7月10日 · AI代理技能项目霸榜日增千星
  • UVa 657 The Die is Cast
  • 基于MA12070与PIC18F26K40的高保真音频系统设计
  • npm 10.x 版本依赖管理实战:3种版本锁定策略与 package-lock.json 解析
  • 工业负载控制方案:TPD2017FN与PIC18F46K42的可靠组合
  • 如何在Word中快速添加APA第7版参考文献格式:完整跨平台指南