Thursday, September 9, 2010

ACM: 127 - "Accordian" Patience

simulation。給52張撲克牌,向左一張或左三張合併同數字或同花色,輸出合併完成後剩下的堆數和每一堆的張數。每合併一次,要檢查是否可以繼續再向左合併。

CODE

#include <iostream>
using namespace std;

#define MAX 52

int main(){
  int i, j, k, moveto;
  char pile[MAX][MAX+MAX], remain[MAX];
  int len[MAX];
  
  while( (cin >> pile[0]) && (pile[0][0] != '#') ){
    len[0] = 2;
    for(i=1; i<MAX; i++){
      cin >> pile[i];
      len[i] = 2;
    }//i: read in all cards
    
    i=1;
    while( i < MAX ){
      moveto = i;
      for(j=i-1; j>=0 && len[j]==0; --j);//1 left
      if( (j >= 0) && (pile[j][ len[j]-2 ] == pile[i][ len[i]-2 ] || pile[j][ len[j]-1 ] == pile[i][ len[i]-1 ]) )
        moveto = j;
      for(--j; j>=0 && len[j]==0; --j);//2 left
      for(--j; j>=0 && len[j]==0; --j);//3 left
      if( (j >= 0) && (pile[j][ len[j]-2 ] == pile[i][ len[i]-2 ] || pile[j][ len[j]-1 ] == pile[i][ len[i]-1 ]) )
        moveto = j;
      if( i != moveto ){
        len[i] -= 2;
        pile[moveto][ len[moveto]++ ] = pile[i][ len[i] ];
        pile[moveto][ len[moveto]++ ] = pile[i][ len[i]+1 ];
        i = moveto;
      }
      else
        for(++i; i<MAX && len[i]==0; ++i);
    }
    
    k = 0;
    for(i=0; i<MAX; i++)
      if( len[i] > 0 )
        remain[k++] = i;
    cout << k << ( k == 1 ? " pile" : " piles" ) << " remaining:";
    for(i=0; i<k; i++)
      cout << ' ' << (len[ remain[i] ] / 2);
    cout << endl;
  }//while
  
  return 0;
}

No comments:

Post a Comment