UVA 246 10-20-30 10-20-30游戏 模拟+STL双端队列deque

Input

Each input set consists of a sequence of 52 integers separated by spaces and/or ends of line. The integers represent card values of the initial deck for that game. The first integer is the top card of the deck. Input is terminated by a single zero (0) following the last deck.

 

Output

For each input set, print whether the result of the game is a win, loss, or a draw, and print the number of times a card is dealt before the game results can be determined. (A draw occurs as soon as the state of the game is repeated.) Use the format shown in the ``Sample Output" section.

 

Sample Input

 

2 6 5 10 10 4 10 10 10 4 5 10 4 5 10 9 7 6 1 7 6 9 5 3 10 10 4 10 9 2 1

10 1 10 10 10 3 10 9 8 10 8 7 1 2 8 6 7 3 3 8 2

4 3 2 10 8 10 6 8 9 5 8 10 5 3 5 4 6 9 9 1 7 6 3 5 10 10 8 10 9 10 10 7

2 6 10 10 4 10 1 3 10 1 1 10 2 2 10 4 10 7 7 10

10 5 4 3 5 7 10 8 2 3 9 10 8 4 5 1 7 6 7 2 6 9 10 2 3 10 3 4 4 9 10 1 1

10   5 10 10 1 8 10 7 8 10 6 10 10 10 9 6 2 10 10

0

 

Sample Output

 

Win : 66

Loss: 82

Draw: 73


写这题算是学了deque的用法,移动牌堆还是类似上题的写法,用pos数组建一个位置到堆的映射,要注意的是,去除一个堆以后下标要自减,以保证下次访问到当前位置的堆,这点是我写的时候没注意到,调试了好久,尴尬。
学了resize和reserve的区别,这两个和效率有关还是值得注意的。记得resize完以后再赋值。
如果是自己写的class,想用set判重,要重载操作符<,可用memcpy实现。

/*
Created by Rey Chen on 2015.7.4
*/

#include<cstdio>

#include<queue>

#include<set>

#include<vector>

using namespace std;

const int maxn  = 53;

char *ans[3] = {"Draw:", "Loss:", "Win :"};







vector<deque<int> >s(8);

deque<int> &hand  = s[0];



int pos[7];

int plSz;

int step;



inline bool pick(deque<int> & x)

{

   int n = x.size();

   int sum;



   if(sum = x[0] + x[1] + x[n-1], sum == 10|| sum == 20 || sum == 30 ){//

      hand.push_back(x[0]); hand.push_back(x[1]);  hand.push_back(x[n-1]);

      x.pop_front(); x.pop_front();  x.pop_back();

      return true;

   }

   if(n>3){

      if(sum = x[0]+x[n-2]+x[n-1], sum == 10|| sum == 20 || sum == 30) {

         hand.push_back(x[0]); hand.push_back(x[n-2]);  hand.push_back(x[n-1]);

         x.pop_front();  x.pop_back(); x.pop_back();

         return true;

      }

      if(sum = x[n-3]+x[n-2]+x[n-1], sum == 10|| sum == 20 || sum == 30) {

         hand.push_back(x[n-3]); hand.push_back(x[n-2]);  hand.push_back(x[n-1]);

         x.pop_back();  x.pop_back();  x.pop_back();

         return true;

      }

   }



   return false;

}





int sovle()

{

   set<vector<deque<int> > > vis;

   vis.insert(s);

   int t,id;

   for(;;){

      for(int i = 0;i < plSz; i++) {

         if(hand.empty())  return 1;

         t = hand.front(); hand.pop_front();

         step++;

         id = pos[i];

         s[id].push_back(t);

         while(s[id].size()>=3 && pick(s[id])) {

            if(s[id].empty()) {

               plSz--;

               if(plSz == 0) return 2;

               for(int j = i;j < plSz;j++) {//移动堆

                  pos[j] = pos[j+1];

               }

               i--;//访问移动后这堆

            }

         }

         if(vis.count(s) == 0) vis.insert(s);

         else return 0;

      }

   }

   return 0;

}



bool read()

{

   int t;

   scanf("%d",&t);

   if(t == 0) return false;



   step = 0;

   for(int i = 1;i <8;i++)

      s[i].clear();

   hand.resize(52);



   for(int i = 0;i <7;i++)

      pos[i] = i+1;

   plSz = 7;



   deque<int>:: iterator it;

   hand[0] = t;

   for(it = hand.begin(), it++; it != hand.end() ; it++)

      scanf("%d",&t), *it = t;

   return true;

}



int main()

{

 //  freopen("in.txt","r",stdin);

   while(read()) {

      int flag = sovle();

      printf("%s %d\n",ans[flag],step);

   }

   return 0;

}

 



你可能感兴趣的:(deque)