搜索题---医生的药方

简介:
这道题最难的地方是当一种药和它的一个后续药品出现后,如何防止其他的后续药品在搜索中出现,因为搜索的时候是按位置顺序探测的,所以位置不是相邻的时候,从下一层回退回来并不知道前面已经有这样的状态。剪枝的条件应该还有,我这个代码还是很慢。

测试用例:

输入:

复制代码
5
2 4 5
1 3
5
2 3
1 2 4
4
0
3
0
0
复制代码
输出:

2
2 3 5 4
4 3 5 1
 

复制代码
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

const int MAXSIZE = 500;//最大药品数目
vector<vector<int> > medicVect;//记录每种药品的后续药
vector<vector<int> >answers;//记录搜索到的所有药方

vector<int> target;//当前药方
vector<int> answer;//当前解法
int n,p,nCount;
bool used[MAXSIZE];//药是否已经出现
int limit[MAXSIZE];//若药品及其后续药出现了,则限制其他后续药再次出现

bool is_Succ(int x,int y)
{//判断y是不是x的后续药
    bool result = false;
    int i;
    for (i=0;i<medicVect[x].size();++i)
    {
        if (medicVect[x][i]==y)
        {
            result = true;
        }
    }
    return result;
}
int is_one_pred(int x)
{//取x的唯一前驱药,若为则说明前驱药不唯一
    int result = 0;
    int i,k;
    k = 0;
    for (i=0;i<n;++i)
    {
        if (is_Succ(i,x)==true)
        {
            if (k==0)
            {
                k = i;
            }
            else
            {
                return result;
            }
        }
    }
    result = k;
    return result;
}
void limit_inc(int x)
{//把x的后续药都标记为不可以再使用
    int i;
    for (i=0;i<medicVect[x].size();++i)
    {
        ++limit[medicVect[x][i]];
    }
}
void limit_dec(int x)
{//撤销x后续药不可以再使用的标记
    int i;
    for (i=0;i<medicVect[x].size();++i)
    {
        --limit[medicVect[x][i]];
    }
}
bool init()
{
    nCount = 0;//解法数
    answer.resize(p+1);
    answer[0] = 0;
    int i,j,k;
    //初始化限制条件,值均为
    for (i=0;i<MAXSIZE;++i)
    {
        limit[i] = 0;
    }
    for (i=2;i<=p-1;++i)
    {
        if (target[i]!=0)
        {
            //若有唯一的前驱药,则后续药不得再次出现,否则无解
            k = is_one_pred(target[i]);
            if (k==0)continue;
            for (j=i+1;j<=p;++j)
            {
                if(is_Succ(k,target[j]))
                    return false;
            }
        }
    }
    //记录已经知道的药(被使用了,可不参与搜索)
    for (i=1;i<=p;++i)
    {
        if (target[i]!=0)
        {
            used[target[i]] = true;
        }
    }
    return true;
}
void Solve(int curPos)
{
    int i,num;
    if (curPos>p)
    {//找到一种解
        //输出一个解法
        answers.push_back(answer);//保存当前解法
        nCount++;//解法数加
        return;
    }
    if (target[curPos]==0)
    {//当前位置药品未知,从前一药品的后续药中进行试探
        for (i=0;i<medicVect[answer[curPos-1]].size();++i)
        {
            num = medicVect[answer[curPos-1]][i];
            if (used[num]==false && limit[num]==0)
            {//符合条件,放置药品下去
                if (curPos>1)
                {//设置限制条件,防止后续药品出现
                    limit_inc(answer[curPos-1]);
                }
                answer[curPos] = num;//放入解法中
                used[num] = true;//被使用了
                Solve(curPos+1);//进入下一个位置的试探
                used[num] = false;//从上一层回来,重置状态
                if (curPos>1)
                {//恢复到原来的限制条件
                    limit_dec(answer[curPos-1]);
                }
            }
        }
    }
    else
    {//第curPos个位置的药已知
        if (curPos>1)
        {
            if (target[curPos-1]==0)
            {//判断是否满足前后继的关系
                if (!is_Succ(answer[curPos-1],target[curPos]))
                {
                    return;
                }
            }
        }
        if (curPos>1)
        {//设置限制条件,防止后续药品出现
            limit_inc(answer[curPos-1]);
        }
        answer[curPos] = target[curPos];//放入解法中
        Solve(curPos+1);//进入下一个位置的试探
        if (curPos>1)
        {//恢复到原来的限制条件
            limit_dec(answer[curPos-1]);
        }
    }
}
int main()
{
    int i,num;
    cin>>n;
    string input;
    getline(cin,input);
    //任何药都是号药的后续药
    vector<int> firstVect;
    for (i=0;i<n;++i)
    {
        firstVect.push_back(i+1);
    }
    medicVect.push_back(firstVect);
    //输入每一种药品的后续药
    for (i=0;i<n;++i)
    {
        vector<int> tmpVect;
        getline(cin,input);
        string::iterator pos = input.begin();
        do 
        {
            string temp;
            pos = find(input.begin(),input.end(),' ');//找到分隔符
            copy(input.begin(),pos,back_inserter(temp));
            num = atoi(temp.c_str());
            tmpVect.push_back(num);
            if (pos==input.end())
            {//最后一个数字了
                break;
            }
            else
            {
                input.erase(input.begin(),++pos);
            }
        } while (pos!=input.end());
        medicVect.push_back(tmpVect);
    }
    //输入给定的药方
    cin>>p;
    target.resize(p+1);
    for (i=1;i<=p;++i)
    {
        cin>>num;
        target[i] = num;
    }
    if (!init())
    {//无解
        cout<<"解法数目: "<<nCount<<endl;
    }
    else
    {
        Solve(1);
        cout<<nCount<<endl;
        vector<vector<int> >::iterator iter;
        for (iter = answers.begin();iter!=answers.end();++iter)
        {
            int size = iter->size();
            for (i = 1;i<size;++i)
            {
                cout<<(*iter)[i]<<" ";
            }
            cout<<endl;
        }
    }
    system("pause");
    return 0;
}
复制代码


本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/11/18/1336080.html,如需转载请自行联系原作者
目录
打赏
0
0
0
0
60
分享
相关文章
文档管理软件中的KMP算法:快速搜索与匹配的秘密武器
KMP算法可以用于文档管理软件中的字符串匹配功能。在监控软件中,需要对用户的电脑活动进行监控,包括监控用户输入的文本内容。为了保护公司的机密信息,监控软件需要检测用户输入的文本中是否包含敏感信息,如公司机密信息、禁止使用的词汇等。
175 0
用citespace对知网文献的关键词分析结果很少如何解决?
用citespace对知网文献的关键词分析结果很少如何解决?
305 0
用citespace对知网文献的关键词分析结果很少如何解决?
基于搜索指数可视化分析近十年的中秋热度
基于搜索指数可视化分析近十年的中秋热度
192 0
基于搜索指数可视化分析近十年的中秋热度
智能推荐:“相关性搜索”只给你最想要的
在过去十年里,搜索已经变得无处不在——搜索框已然成为各类网站、应用的基础标配。一个网站或者应用不提供搜索框,这是无法想象的事情。随着搜索在基础架构方面越来越多的难题得到解决,加之解决方案的商品化进程,搜索引擎的竞争已经从如何提供快速、可伸缩的搜索,转变成如何针对用户的信息需求提供最相关的匹配。
2765 0
《SEO的艺术(原书第2版)》——1.3 人类搜索的目标
本节书摘来自华章计算机《SEO的艺术(原书第2版)》一书中的第1章,第1.3节,作者:(美)恩吉(Enge, E.)著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1729 0
《SEO的艺术(原书第2版)》——1.5 人们如何搜索
本节书摘来自华章计算机《SEO的艺术(原书第2版)》一书中的第1章,第1.5节,作者:(美)恩吉(Enge, E.)著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1146 0
《SEO的艺术(原书第2版)》——2.3 确定搜索者意图并交付相关、新鲜的内容
本节书摘来自华章计算机《SEO的艺术(原书第2版)》一书中的第2章,第2.3节,作者:(美)恩吉(Enge, E.)著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1155 0
《SEO的艺术(原书第2版)》——第1章 搜索:反映认知、连接商务
本节书摘来自华章计算机《SEO的艺术(原书第2版)》一书中的第1章,作者:(美)恩吉(Enge, E.)著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1126 0
《SEO的艺术(原书第2版)》——1.4 确定搜索者意图:营销人员和搜索引擎面临的共同挑战
本节书摘来自华章计算机《SEO的艺术(原书第2版)》一书中的第1章,第1.4节,作者:(美)恩吉(Enge, E.)著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1306 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等