2014亞馬遜線上筆試題目及解決方案(MMChess問題)

菜鳥加貝的爬升發表於2013-10-01

 整體思路:關鍵是需要知道當前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 }

 

相關文章