Monday, September 6, 2010

ACM: 124 – Following Orders

真開心再用vector寫出了這題,嘗試用vector的push_back()及erase()產生所有的組合。在取出元素時檢查未被取出的元素是否有小於該元素的元素(小的元素應該先被取出)。

這題是給一些元素,再給其中部分元素的大小關係,依字典順序輸出在給定的大小關係下所有可能的元素組合。

CODE

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

#define MAX_LET 26

vector<char> vars; //variables
bool consts[MAX_LET][MAX_LET]; //constraints

void sort_vars(int left, int right);
void comb(vector<char> current, vector<char> pool);

int main(){
  int i, j;
  char c, d1, d2;
  bool flag = false;
  
  for(i=0; i<MAX_LET; i++)
    for(j=0; j<MAX_LET; j++)
      consts[i][j] = false;
  
  while( (c = getchar()) != EOF ){
    if( c >= 'a' && c <= 'z' ){
      vars.push_back(c);
    }//get variables
    else if( c == '\n' ){
      while( (d1 = getchar()) != '\n' ){
        if( d1 >= 'a' && d1 <= 'z' ){
          cin >> d2;
          consts[d2-'a'][d1-'a'] = true;
        }
      }//while get constraints
      
      if(flag == true)
        puts("");
      sort_vars(0, vars.size()-1); //sort variables
      vector<char> tmp;
      comb(tmp, vars); //produce combinations
      
      //initialize
      flag = true;
      vars.clear();
      for(i=0; i<MAX_LET; i++)
        for(j=0; j<MAX_LET; j++)
          consts[i][j] = false;
    }//get constraints
  }  
  
  return 0;
}

void sort_vars(int left, int right){
  if( left < right ){
    int i = left + 1;
    int j = right;
    
    while(1){
      for(; (i<=right) && (vars[i] <= vars[left]); i++);
      for(; (j>left) && (vars[j] > vars[left]); j--);
      if( i>=j )
        break;
      swap(vars[i], vars[j]);
    }
    swap(vars[j], vars[left]);
    sort_vars(left, j-1);
    sort_vars(j+1, right);
  }
}

void comb(vector<char> current, vector<char> pool){
  vector<char>::size_type i, j;
  if( pool.empty() ){
    for(i=0; i!=current.size(); i++)
      cout << current[i];
    cout << endl;
    return;
  }
  
  vector<char> tmp_cur, tmp_pool;
  vector<char>::size_type psize = pool.size();
  for(i=0; i<psize; i++){
    for(j=0; j<psize; j++){
      if( consts[ pool[i]-'a' ][ pool[j]-'a' ] )
        break;
    }
    if( j == psize ){
      tmp_pool = pool;
      tmp_cur = current;
      tmp_cur.push_back(pool[i]);
      tmp_pool.erase(tmp_pool.begin()+i);
    
      comb(tmp_cur, tmp_pool);
    }
  }//i
  return;
}

No comments:

Post a Comment