zoukankan      html  css  js  c++  java
  • 题解报告——程序补丁

    程序补丁(bugs)

    时间限制: 1000 ms         内存限制: 65536 KB

    【题目描述】

    一个程序总有个错误,公司经常发布补丁来修正这些错误,遗憾的是,每用一个补丁,在修正某些错误的时候,同时会加入某些错误,每个补丁都有一定运行时间。

    某公司发表了一个游戏,出现了n个错误B={b1,b2,b3,……bn},于是该公司发布了m个补丁,每个补丁的应用都是有条件的(即哪些错误必须存在,哪些错误不能存在)。

    求最少需要多少时间可全部修正这些错误。

    【输入】

    输入文件第一行有两个正整数n和m,n表示错误总数,m表示补丁总数,1≤n≤20,1≤m≤100。接下来m行给出了m个补丁的信息。每行包括一个正整数(表示此补丁程序的运行时间)和两个字符串,

    第一个字符串描述了应用该补丁的条件。字符串的第i个字符,如果是‘+’,表示在软件中必须存在第bi号错误;如果是‘-’,表示软件中错误bi不能存在;如果是‘0’,则表示错误bi存在或不存在均可(即对应用该补丁没用影响)。

    第二个字符串描述了应用该补丁的效果。字符串的第i个,如果是‘+’,表示产生了一个新错误bi;如果是‘-’,表示错误bi被修改好了;如果是‘0’,则表示错误bi不变(即原来存在的,仍然存在;原来不存在,还是不存在)。

    【输出】

    输出一个整数,如果问题有解,输出总耗时。否则输出-1。

    【输入样例】

    3 5
    1 0-+ -+-
    3 +-- -00
    4 000 00-
    6 +0+ -0-
    3 0+0 0-0

    【输出样例】

    7

    【思路分析】

    这道题首先就会想到是状态压缩,但由于是求最短用时所以我们不用动规,改写spfa。

    首先将每种状态记录在一个节点中,每次扩展更新从起点到每个节点的最短路(只要可以从一个状态到另一个状态就可以更新)

    这道题其实非常考验位运算,是一道练习位运算的很好的题,具体位运算的精髓还是在代码里去领悟吧!!!

    【代码实现】

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #include<iostream>
     5 using namespace std;
     6 queue<int> que;
     7 const int MAXN=(1<<20)+7;
     8 int b1[105],b2[105],f1[105],f2[105],t1[105],n,m;
     9 int dis[MAXN];
    10 bool vis[MAXN];
    11 void spfa()
    12 {
    13     memset(vis,false,sizeof(vis));
    14     memset(dis,0x3f3f3f3f,sizeof(dis));
    15     int s=(1<<n);s--;
    16     que.push(s);
    17     vis[s]=true;
    18     dis[s]=0;
    19     while(!que.empty())
    20     {
    21         int now=que.front();
    22         que.pop();
    23         vis[now]=false;
    24         for(int i=1;i<=m;i++)
    25         {
    26             if(((b1[i]&now)==b1[i])&&((b2[i]&now)==0))
    27             {
    28                 int son;
    29                 son=(now|f2[i]);
    30                 son=(son&(~f1[i]));
    31                 if(dis[son]>dis[now]+t1[i])
    32                 {
    33                     dis[son]=dis[now]+t1[i];
    34                     if(!vis[son])
    35                     {
    36                         que.push(son);
    37                         vis[son]=true;
    38                     }
    39                 }
    40             }
    41         }
    42     }
    43 }
    44 int main()
    45 {
    46     scanf("%d%d",&n,&m);
    47     for(int i=1;i<=m;i++)
    48     {
    49         char bb[20],ff[20];
    50         int tt;
    51         cin>>tt;
    52         cin>>bb>>ff;
    53         t1[i]=tt;
    54         for(int j=0;j<n;j++)
    55         {
    56             if(bb[j]=='+') b1[i]=b1[i]|(1<<j);
    57             if(bb[j]=='-') b2[i]=b2[i]|(1<<j);
    58             if(ff[j]=='-') f1[i]=f1[i]|(1<<j);
    59             if(ff[j]=='+') f2[i]=f2[i]|(1<<j);
    60          }
    61     }
    62     spfa();
    63     if(dis[0]==0x3f3f3f3f) printf("-1");
    64     else printf("%d",dis[0]);
    65     return 0;
    66 }
  • 相关阅读:
    ASP.NET之电子商务系统开发1(数据列表)
    ASP.NET之电子商务系统开发2(购物车功能)
    MFC之列表控件
    自己动手写操作系统(二)一个最小的“操作系统”
    自己动手写操作系统(一)环境准备
    windows常用快捷键
    MFC之下拉框
    链表反转&交换链表结点
    TinyHttp前置知识
    单链表基本操作总结
  • 原文地址:https://www.cnblogs.com/genius777/p/8658604.html
Copyright © 2011-2022 走看看