1. 原題

Throwing cards away I
  Given is an ordered deck of
n cards numbered 1 to n with card 1 at the top and card n at the bottom. The
following operation is performed as long as there are at least two cards in the
deck:
  Throw away the top card and move the
card that is now on the top of the deck to the bottom of the deck.
Your task is to find the sequence of discarded cards and the last, remaining
card.

Input Each line of input (except the last) contains a number n ≤ 50. The last
line contains ‘0’ and this line should not be processed.

Output For each number from the input produce two lines of output. The first
line presents the sequence of discarded cards, the second line reports the last
remaining card. No line will have leading or trailing spaces. See the sample
for the expected format.

Sample Input

7 19 10 6 0

Sample Output

Discarded cards: 1, 3, 5, 7, 4, 2

Remaining card: 6

Discarded cards: 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 4, 8, 12, 16, 2,
10, 18, 14

Remaining card: 6

Discarded cards: 1, 3, 5, 7, 9, 2, 6, 10, 8

Remaining card: 4

Discarded cards: 1, 3, 5, 2, 6

Remaining card: 4

  1.  

題目描述:桌上有n(n<=50)張牌,從第一張開始,從上往下依次編號為1-n。當至少還剩下兩張牌時進行以下操作:把第一張牌扔掉,然後把新的第一張牌放到整疊牌的最後。輸入每行包含一個n,輸出每次扔掉的牌以及最後剩下的牌。

此題可以用佇列的方式解題,佇列是一種特殊的線性結構,只允許在佇列的首部(head)進行刪除,成為“出隊”,而在佇列的首部(tail)進行插入,稱為“入隊”。

佇列解題思路如下:

第一步,要將第一個數刪除,先想一下怎麼將陣列的第一個數刪除呢,最簡單的方法就是將所有的數都往後挪一位,將前面的數覆蓋。但是如果每次都挪一次,很耗費時間。在此題中,我們引入整型變數head和tail,head用來記錄佇列的第一位,tail記錄最後一位的下一個位置(這裡tail記錄最後一位的下一個位置是因為當佇列只剩下一個元素時,第一位會和最後一位重合)。每當刪除一個數,head++,浪費一個空間,但可以節省很多時間,新增加一個數也是,把需要增加的數放到隊尾即a【tail】之後再tail++就可以了。

注意:輸出格式,當n=1時,“Discarded cards:”後沒有空格。

  1. 下面是程式碼(已執行通過)
  2.  
  1. #include<iostream>
  2.  
  3. using namespace std;
  4.  
  5. int s[]; //佇列的主體,用來儲存內容
  6.  
  7. int n;
  8.  
  9. int main()
  10.  
  11. {
  12.  
  13. while(cin>>n&&n)
  14.  
  15. {
  16.  
  17. int head=;
  18.  
  19. int tail=n; //head為隊首,tail為隊尾即n
  20.  
  21. for(int i=;i<=n;i++)
  22.  
  23. {
  24.  
  25. s[i]=i;
  26.  
  27. }
  28.  
  29. if(n==)
  30.  
  31. {
  32.  
  33. cout<<"Discarded cards:"<<endl<<"Remaining card: 1"<<endl;
  34.  
  35. }
  36.  
  37. else
  38.  
  39. {
  40.  
  41. cout<<"Discarded cards: ";
  42.  
  43. while(head<tail)
  44.  
  45. {
  46.  
  47. cout<<s[head];head++;
  48.  
  49. if(head<tail)
  50.  
  51. cout<<", ";
  52.  
  53. if(head==tail)
  54.  
  55. cout<<endl<<"Remaining card: "<<s[head]<<endl;
  56.  
  57. s[++tail]=s[head];
  58.  
  59. head++;
  60.  
  61. }
  62.  
  63. }
  64.  
  65. }
  66.  
  67. return ;
  68.  
  69. }