/* 问题描述: 著名医生的药方 很久以前,有一个医术非常高明的医生,曾经医治好了很多怪病。 但是,他开出的药方的字迹却是十分难以辨认,只有他自己和他自己的药剂师 才能读懂他的药方。有时候甚至是两个不同的药方的同一种药都是难以辨认出的。 不过,这个医生开药方的时候,习惯有一个固定的标准模式。他有一个药材库,里面共有 n种药,出了这n种药,他不会使用任何其他的药,对于每一种药,都有一个关于他的后续药 的集合,只有这种药的后续药才能够直接出现在这种药的下一个位置。当然,任何一种药 都可能同时是几种药的后续药。 这个医生开出的药房是一个列表的形式。在他的一个药房中,一种药只可能出现一次。 更奇怪的是,当他开出一种药和他的后续药以后,这种药的其他后续药就不可能出现在这之后的 序列中。 后来,一些书法家和医生共同分析了这个医生的大量药方,写出了他的所有药的清单。这里我们 有n个整数1,2,...,n来依次表示他的n种药。同时,他们也分析出了每一种药的可能的后续的药单。 现在,有一个关于这个医生的药方,药方中写有p种药。可惜的是药方中有一些药并没有具体的辨别出。 那么请你写一个程序,帮忙辨别出药方中不确认的药。当然对于不确定的药,可能可以构造出多种不同的 药方,那么请你找出所有的情况。 输入格式: 输入文件doctor.in的第一行只有一个整数n(0<n<=500),表示所有的药的种数。 在接下来的n行中,每行都有若干个数(中间用空格隔开),第i行表示的第i种药的后续 药的集合。再接下来的一行,又有一个整数p,表示具体的一个药方的药的数目。继续下来的p行, 每行有一个整数,表示这个药方第i个药被鉴别出来时k;如果k是0,表示这个药还没有被鉴别出来。 输出格式: 输出文件doctor.out的第一行是一个整数m,表示总共可已构造出m种不同的药方。接下来的m行, 每行应该有p个数,具体输出每一种情况的药方,中间用一个空格格开。所有的m行的输出,必须按照整数排序 顺序输出,行首行末无空格。 输入输出样例: ========================================================================= 样例1: Sample Input Output for the input 5 2 2 4 5 2 3 5 4 1 3 4 3 5 1 5 2 3 1 2 4 4 0 3 0 0 ========================================================================= ========================================================================= 样例2: Sample Input Output for the input 1 1 1 1 1 0 ========================================================================= ========================================================================= 样例3: Sample Input Output for the input 10 12 3 4 7 4 8 6 5 2 1 5 6 4 8 6 10 2 2 4 6 10 4 8 6 10 3 1 8 9 9 5 6 7 4 2 6 9 5 6 10 3 5 7 10 9 8 6 10 2 4 9 9 8 6 10 3 1 4 6 7 9 10 2 6 7 4 5 8 10 2 6 7 9 2 3 5 10 3 6 7 9 5 10 5 6 7 4 0 10 5 6 7 9 0 6 0 0 ========================================================================= */ /* Notice:为了方便我是从控制台输入输出的 */ /* @author aa_niaofang 2011-4-14 23:43:25 */ #include <stdio.h> #include <stdlib.h> #define M 10 struct save { int *link; struct save *next; }; /*global variable*/ struct save *Global_save=NULL;/*用来存储可能的药方*/ int count=0;/*用来计数可能药方的个数*/ /*定义两个值: 一个是药方中本来就有的药方 另一个是已经成功选择了的药方 */ /*药方中本来就有的药方*/ int *exsit=NULL; /*对药方是否使用进行标志*/ int *used=NULL; void search(int **,int*,int k,int p,int n);/*主要查找函数*/ bool van(int k,int i,int**a);/*判断i是否是k的前序药方*/ bool subsequnce(int k,int i,int**a);/*判断i是否是k的后续药方*/ void main() { int n; int p; int i,j; printf("Input the total number kinds of the priscreptions!/n"); scanf("%d",&n); int **a=(int **)malloc(sizeof(int *)*n); for(i=0;i<n;i++) { a[i]=(int*)malloc(sizeof(int)*M); } printf("Input the priscreption!/n"); for(i=0;i<n;i++) { j=0; int c; while(1) { scanf("%d",&c); a[i][j++]=c; if(getchar()=='/n') break; } a[i][j]=0; } printf("Input the priscreption number which been choosed!/n"); scanf("%d",&p); int *b=(int *)malloc(sizeof(int)*p); exsit=(int *)malloc(sizeof(int)*n+1); used=(int *)malloc(sizeof(int)*n+1); for(i=0;i<n+1;i++) { exsit[i]=0; used[i]=0; } printf("Input the priscreption which been choosed!/n"); for(i=0;i<p;i++) { scanf("%d",&b[i]); if(b[i]) { exsit[b[i]]=1; } } j=0; struct save *s=NULL; search(a,b,j,p,n); /*输出*/ s=Global_save; printf("%d/n",count); for(i=0;i<count;i++) { for(j=0;j<p;j++) { printf("%d ",(s->link)[j]); } printf("/n"); s=s->next; } } void search(int **a,int *b,int k,int p,int n) { if(k+1>p) { count++; struct save *s=(struct save*)malloc(sizeof(struct save)); s->link=(int *)malloc(sizeof(int)*p); s->next=NULL; for(int i=0;i<p;i++) { (s->link)[i]=b[i]; } if(Global_save==NULL) { Global_save=s; } else { struct save *t=Global_save; while(t->next) { t=t->next; } t->next=s; } return; } /*If k is the last prescription*/ if(k+1==p) { if(k==0) { b[k]=a[0][0]; search(a,b,k+1,p,n); return; } if(exsit[b[k]]==0) { int k1=k-1; for(int x=0;x<M && a[b[k1]-1][x];x++) { int flag=0; for(int j=0;j<k1;j++) { if(subsequnce(b[j],a[b[k1]-1][x],a) || a[b[k1]-1][x]==b[j]) { flag=1; break; } } if(flag==0 && used[a[b[k1]-1][x]]==0) { b[k]=a[b[k1]-1][x]; used[b[k]]=1; search(a,b,k+1,p,n); used[b[k]]=0; if(exsit[b[k]]==0) b[k]=0; } } } return; } if(exsit[b[k]]==0) { if(k==0) { for(int i=0;i<n;i++) { int flag=0; for(int j=k+2;j<p;j++) { if(van(b[j],i+1,a)) { flag=1; break; } } if(flag==1) continue; if(b[k+1]==0 && used[i+1]==0) { b[k]=i+1; used[b[k]]=1; search(a,b,k+1,p,n); used[b[k]]=0; if(exsit[b[k]]==0) b[k]=0; } else { for(int j=0;j<M && a[i][j];j++) { if(a[i][j]==b[k+1] && used[i+1]==0) { b[k]=i+1; used[i+1]=1; search(a,b,k+1,p,n); used[b[k]]=0; if(exsit[b[k]]==0) b[k]=0; } } } } } else { int k1=b[k-1]; for(int i=0;i<M &&a[k1-1][i];i++) { int flag=0; for(int x=0;x<k;x++) { if(a[k1-1][i]==b[x]) { flag=1; break; } } if(k-2>=0 && flag==0) { for(int j=0;j<k-1;j++) if(subsequnce(b[j],a[k1-1][i],a)) { flag=1; break; } } for(int j=k+2;j<p && flag==0;j++) { if(van(b[j],a[k1-1][i],a)) { flag=1; break; } } if(flag==0) { if(b[k+1]==0 && used[a[k1-1][i]]==0) { b[k]=a[k1-1][i]; used[b[k]]=1; search(a,b,k+1,p,n); used[b[k]]=0; if(exsit[b[k]]==0) b[k]=0; } else { for(int x=0;x<M &&a[a[k1-1][i]-1][x];x++) { if(b[k+1]==a[a[k1-1][i]-1][x] && used[a[k1-1][i]]==0) { b[k]=a[k1-1][i]; used[b[k]]=1; search(a,b,k+1,p,n); used[b[k]]=0; if(exsit[b[k]]==0) b[k]=0; break; } } } } } } } else { if(used[b[k]]==0) { used[b[k]]=1; search(a,b,k+1,p,n); used[b[k]]=0; if(exsit[b[k]]==0) b[k]=0; } } } /* 查找i是否为k前驱 */ bool van(int k,int i,int **a) { if(i==0) return false; for(int j=0;j<M && a[i-1][j];j++) { if(a[i-1][j]==k) return true; } return false; } /* 查找i是否为k的后继 */ bool subsequnce(int k,int i,int **a) { if(i==0) return false; for(int j=0;j<M && a[k-1][j];j++) { if(a[k-1][j]==i) return true; } return false; }

回溯法实例----著名医生的药方相关推荐

  1. 回溯法实例详解(转)

    概念 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就"回溯"返回,尝试别的路径. 回溯法是一种选优搜索法,按选优条件向前 ...

  2. python回溯方法的模板_Python基于回溯法子集树模板解决0-1背包问题实例

    本文实例讲述了Python基于回溯法子集树模板解决0-1背包问题.分享给大家供大家参考,具体如下: 问题 给定N个物品和一个背包.物品i的重量是Wi,其价值位Vi ,背包的容量为C.问应该如何选择装入 ...

  3. python回溯方法的模板_实例讲解Python基于回溯法子集树模板实现图的遍历功能

    这篇文章主要介绍了Python基于回溯法子集树模板实现图的遍历功能,结合实例形式分析了Python使用回溯法子集树模板针对图形遍历问题的相关操作技巧与注意事项,需要的朋友可以参考下 本文实例讲述了Py ...

  4. 算法设计与分析第5章 回溯法(一)【回溯法】

    第5章 回溯法 5.1 回溯法 1.回溯法的提出  有许多问题,当需要找出它的解集或者要求回答什么解是满足某些约束条件的最佳解时,往往要使用回溯法. 2. 问题的解空间 (1)问题的解向量:回溯法希望 ...

  5. 五大经典算法之回溯法

    一.基本概念   回溯法,又称为试探法,按选优条件向前不断搜索,以达到目标.但是当探索到某一步时,如果发现原先选择并不优或达不到目标,就会退回一步重新选择,这种达不到目的就退回再走的算法称为回溯法. ...

  6. 七十八、 回溯法解决八皇后问题

    @Author:Runsen 八皇后问题 八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后. 来自百度百科,皇后的走法是可 ...

  7. 4.Python算法之试探算法思想(回溯法)

    1.什么是试探算法? 2.试探算法的解题的基本步骤 3.试探算法的思想 4.试探算法适合的问题 5.试探算法解决"八皇后"的问题 1.什么是试探算法?   试探算法也叫回溯法,试探 ...

  8. 算法设计之—直接 遍历/穷举法、贪心算法、动态规划、回溯法、EM方法

    算法是对完成特定问题的程序执行序列描述,表象为从问题初始状态到问题结束状态的所有路径之中寻找可行路径,若无先验经验,根据执行方式不同可以划分为无规则和有规则(启发式)方法. 无规则方法为穷举,改进方法 ...

  9. python找零钱问题_Python基于回溯法子集树模板解决找零问题示例

    本文实例讲述了Python基于回溯法子集树模板解决找零问题.分享给大家供大家参考,具体如下: 问题 有面额10元.5元.2元.1元的硬币,数量分别为3个.5个.7个.12个.现在需要给顾客找零16元, ...

最新文章

  1. 思念水饺吃成泡沫水饺(图)思念质量门
  2. kafka的安装与启动运行
  3. Java编程入门100例之二十二(字符串查找)
  4. gevent+django并发资料调研
  5. 服务器主机装普通系统后性能下降,服务器主机性能分析
  6. android 抽象方法作用,android – 类必须声明为abstract或实现抽象方法
  7. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第5篇]复杂性类NP是什么意思?
  8. 前端周报:前端面试题及答案总结;JavaScript参数传递的深入理解
  9. group by 和where 条件后面不能用刚设置的别名。
  10. 今天看到一个热搜,说一个美团会员配送费6元,普通用户2元,导致轩然大波
  11. The developer claims that Bpytop
  12. 78oa mysql_78OA系统安装后无法打开解决方案
  13. Android嵌套滑动冲突
  14. 第四章 网络层[练习题+课后习题]
  15. HDU6135 拓展KMP模板
  16. 浏览器兼容性测试工具
  17. linux asm 裸设备,为ASM生成裸设备
  18. linux 显卡优化软件,NVClock:优化 Nvidia 显卡
  19. 高数定理、法则(持续添加)
  20. 计算与背景反差较大显示明显的前景色

热门文章

  1. 教给论文投稿小白们去投哪些靠谱的国际学术会议
  2. Ubuntu20.04 PostgreSQL 14 安装配置记录
  3. 纳德拉干得不错!微软股价逼近14年最高点
  4. 用一元五角人民币兑换五分,二分和一分的硬币(每种都要有)共100枚,共有几种兑换方案,每种共兑换多少枚
  5. C语言:实验2-3-5 输出华氏-摄氏温度转换表.2021-07-16
  6. 蓝桥杯 PREV-43 拉马车(试题解析)
  7. python位置参数错误_python-2.7 – python:组合位置和可选参数时argparse抛出值错误...
  8. Qt官方示例-计算器
  9. 计算机组装与维护褚建立答案,计算机组装与维护_课程标准
  10. 为什么离不开 Stackoverflow