2014亚马逊在线笔试题目及解决方案(MMChess问题)

 整体思路:关键是需要知道当前Steps数组中的全排列即可,而且需要不重复的全排列。即关键在于非递归的全排列实现即可~ 其实直接利用STL中的next_permutation算法的,这里我又自己实现了一遍该算法,当练练手了~

  1 #include <iostream>
  2 #include <fstream>
  3 #include <string>
  4 #include <istream>
  5 #include <algorithm>
  6 
  7 using namespace std;
  8 
  9 void Swap(int& a, int&b)
 10 {
 11     int tmp = a;
 12     a = b;
 13     b = tmp;
 14 }
 15 
 16 void ReverseArr(int *arr, int nBegin, int nEnd)
 17 {
 18     while (nBegin < nEnd)
 19     {
 20         Swap(arr[nBegin],arr[nEnd]);
 21         nBegin++;
 22         nEnd--;
 23     }
 24 }
 25 
 26 int printArr(int *nCard, int nCountOfCard, int *nStep, int nCountOfStep)
 27 {
 28     // 将当前结果输出,返回最大值
 29     int  nValue = nCard[0];
 30     cout<<"Card["<<0<<"]"<<"("<<nCard[0]<<")+";
 31     int  nIndexOfCards = 0;
 32     for (int i = 0; i!=nCountOfStep; i++)
 33     {
 34         // 取出等式中的结果
 35         int nIndex = nStep[i];
 36         nIndexOfCards += nIndex;
 37         nValue += nCard[nIndexOfCards];
 38         cout<<"Card["<<nIndexOfCards<<"]"<<"("<<nCard[nIndexOfCards]<<")";
 39 
 40         if (i == nCountOfStep - 1)
 41         {
 42             cout<<" = "<<nValue;
 43         }
 44     }
 45 
 46     cout<<endl;
 47 
 48     cout<<"步骤为:";
 49     for (int i=0; i!= nCountOfStep; i++)
 50     {
 51         cout<<nStep[i]<<" ";
 52     }
 53 
 54     cout<<endl;
 55     return nValue;
 56 }
 57 
 58 
 59 // nCard 记录每一张卡片代表的值
 60 int GetTheMostValue(int *nCard, int nCountOfCard, int *nStep, int nCountOfSteps)
 61 {
 62     // 获取步骤数的全排列  然后根据每个步骤则可以得到最终的value  然后选其中最大的即可
 63     sort(nStep,nStep+nCountOfSteps);
 64     //
 65     int nResult = 0;
 66     while(1)
 67     {
 68         int nValue = printArr(nCard,nCountOfCard,nStep,nCountOfSteps);
 69 
 70         if (nValue > nResult)
 71         {
 72             nResult = nValue;
 73         }
 74 
 75         for (int i = nCountOfSteps - 2; i >= 0; i--)
 76         {
 77             bool bFlag = false;
 78             int ii  = i+1;
 79             if (nStep[i] < nStep[ii])
 80             {
 81                 // 找到相邻的 升序了
 82                 for (int j = nCountOfSteps-1; j >= 0; j--)
 83                 {
 84                     if (nStep[j] > nStep[i])
 85                     {
 86                         Swap(nStep[j],nStep[i]);
 87                         // 然后从ii开始到尾部 进行逆序]
 88                         ReverseArr(nStep,ii,nCountOfSteps-1);
 89                         // 设置标志位  跳出两层循环
 90                         bFlag = true;
 91                         break;
 92                     }
 93                 }
 94                 // 跳出外层循环
 95                 if (bFlag)
 96                 {
 97                     break;
 98                 }
 99             }
100             else if (i == 0)
101             {
102                 // 已经结束
103                 return nResult;
104             }
105         }
106     }
107 }
108 
109 
110 int main()
111 {
112     fstream  file;
113     file.open("E:\\2.txt");
114     if (file.is_open(),ios::in)
115     {
116         int nCountOfCard;
117         int nCountOfStep;
118         string str;
119         // 读取卡片数量和步数的个数
120         file>>nCountOfCard>>nCountOfStep;
121 
122         int *cards = new int[nCountOfCard];
123         int *steps = new int[nCountOfStep];
124         
125         for (int i = 0; i!= nCountOfCard; i++)
126         {
127             file>>cards[i];
128         }
129 
130         for (int j = 0; j!= nCountOfStep; j++)
131         {
132             file>>steps[j];
133         }
134 
135         //计算各个组合~
136         // 其实就是将步骤数进行全排列 然后将每种组合结果输出即可~~ 在此过程中进行比较
137         // 使用非递归的方法吧
138         int nMaxValue = GetTheMostValue(cards,nCountOfCard,steps,nCountOfStep);
139         cout<<"最大的结果为:"<<nMaxValue<<endl;
140 
141 
142         delete[] steps;
143         delete[] cards;
144     }
145     file.close();
146     return 0;
147 }

 

posted @ 2013-10-01 21:10  菜鸟加贝的爬升  阅读(1838)  评论(0编辑  收藏  举报