river.cpp
上传用户:hzc5906
上传日期:2022-06-30
资源大小:8k
文件大小:4k
源码类别:

控制台编程

开发平台:

Visual C++

  1. /************************************************************************/
  2. /*             解决商人渡河问题                                         */
  3. /************************************************************************/
  4. #include <iostream>
  5. #include <vector>
  6. #include <algorithm>
  7. #include <cmath>
  8. #include <stack>
  9. using namespace std;
  10. class CPoint
  11. {
  12. public:
  13. CPoint(int a = -1, int b = -1) :x(a), y(b) {}
  14. CPoint(const CPoint& pt): x(pt.x), y(pt.y) {}
  15. CPoint& operator=(const CPoint &pt)
  16. {
  17. x=pt.x;
  18. y=pt.y;
  19. return *this;
  20. }
  21. int x;
  22. int y;
  23. };
  24. /////////////////////////////////////////////////////////////////////////////
  25. //
  26. inline bool operator==(const CPoint &pt1, const CPoint& pt2)
  27. return pt1.x==pt2.x && pt1.y==pt2.y; 
  28. }
  29. inline bool operator!=(const CPoint &pt1, const CPoint& pt2)
  30. return pt1.x!=pt2.x || pt1.y!=pt2.y; 
  31. }
  32. inline CPoint operator+(const CPoint& pt1, const CPoint& pt2)
  33. return CPoint(pt1.x+pt2.x, pt1.y+pt2.y); 
  34. }
  35. inline CPoint operator-(const CPoint& pt1, const CPoint& pt2)
  36. {
  37. return CPoint(pt1.x-pt2.x, pt1.y-pt2.y); 
  38. }
  39. inline ostream& operator<<(ostream &out, const CPoint &pt)
  40. {
  41. out << '(' << pt.x << ',' << pt.y << ')';
  42. return out;
  43. }
  44. //
  45. ///////////////////////////////////////////////////////////////////////////
  46. // input
  47. void print(vector<CPoint>& st)
  48. {
  49. for(vector<CPoint>::iterator it = st.begin(); it != st.end(); ++it)
  50. {
  51. cout << *it;
  52. }
  53. cout << endl << endl;
  54. }
  55. /*
  56.  * Param k: 第K步
  57.  *  Param pt1: 第k-1步时A岸状态
  58.  *  Param pt2: 第k-1步时B岸状态
  59.  *  Param pt4: A岸的终止点状态
  60.  *  Param state: 允许状态数组
  61.  *  Param dec: 允许决策数组
  62.  *  Param avec: A岸已出现过的状态,不允许再出现
  63.  *  Param avec: B岸已出现过的状态,不允许再出现
  64.  *  return: 解决方案的个数
  65.  */
  66. int step(int k, CPoint& pt1, CPoint& pt2, CPoint& pt4,
  67.   vector<CPoint>& state, vector<CPoint>& dec, vector<CPoint>& avec, vector<CPoint>& bvec)
  68. {
  69. static vector<CPoint> st; //存储每一次决策
  70. static int cnt = 0;
  71. if(pt1 == pt4)
  72. {
  73. ++cnt;
  74. print(st); //输出每一次决策
  75. return cnt; //返回方法的种数
  76. }
  77. CPoint pt5 = pt1, pt6 = pt2; //pt5--state of land-A, pt6--state of land-B
  78. CPoint pt3;
  79. for(vector<CPoint>::iterator it = dec.begin(); it != dec.end(); ++it)
  80. {
  81. if(k%2) //A-->B
  82. pt3 = pt2 + *it;
  83. else //B-->A
  84. pt3 = pt1 + *it;
  85. if(find(state.begin(), state.end(), pt3) != state.end())
  86. {
  87. if(k%2 && find(bvec.begin(), bvec.end(), pt3) != bvec.end()) //A-->B
  88. continue;
  89. if(k%2==0 && find(avec.begin(), avec.end(), pt3) != avec.end()) //B-->A
  90. continue;
  91. if(k%2) //A-->B
  92. {
  93. pt5 = pt1 - *it; 
  94. pt6 = pt2 + *it;
  95. }
  96. if(k%2==0) //B-->A
  97. {
  98. pt5 = pt1 + *it;
  99. pt6 = pt2 - *it;
  100. }
  101. if(k%2)//A-->B
  102. bvec.push_back(pt6);
  103. else
  104. avec.push_back(pt5);
  105. st.push_back(*it);
  106. step(k+1, pt5, pt6, pt4, state, dec, avec, bvec);
  107. st.pop_back();
  108. if(k%2)//A-->B
  109. bvec.pop_back();
  110. else 
  111. avec.pop_back();
  112. }
  113. }
  114. return cnt;//返回方法的种数
  115. }
  116. int main()
  117. {
  118. //MerchantNum--商人数,ServantNum--随从数, 
  119. //Cnt1--仆人比商人多Cnt1时发生抢劫, Cnt2--船的最大负荷
  120. const int MerchantNum = 3, ServantNum = 3, Cnt1 = 0, Cnt2 = 2;
  121. //允许状态向量
  122. vector<CPoint> state;
  123. int i = 0;
  124. for(; i <= MerchantNum; ++i) //生成状态向量
  125. for(int j = 0; j <= ServantNum; ++j)
  126. {
  127. if(!(j-i > Cnt1 || (ServantNum-j) - (MerchantNum-i) > Cnt1) || !i || MerchantNum==i)//不发生抢劫的情况
  128. state.push_back(CPoint(i, j));
  129. }
  130. //允许决策向量
  131. vector<CPoint> dec;
  132. for(i = 0; i <= MerchantNum; ++i)//生成决策向量
  133. for(int j = 0; j <= ServantNum; ++j)
  134. {
  135. if(j+i <= Cnt2 && i+j >= 1)
  136. dec.push_back(CPoint(i, j));
  137. }
  138. //pt1为land-A的初始情况,pt2为land-B的初始情况,pt4为land-A的终止情况
  139. CPoint pt1(MerchantNum, ServantNum), pt2(0,0), pt4(0,0);
  140. vector<CPoint> avec, bvec;
  141. avec.push_back(CPoint(MerchantNum,ServantNum));
  142. int n = step(1, pt1, pt2, pt4, state, dec, avec, bvec);
  143. cout << n << endl;
  144. return 0;
  145. }