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;
}

 



posted @ 2015-07-04 00:24  陈瑞宇  阅读(441)  评论(0编辑  收藏  举报