这道题在数据结构这一章里算是简单的,但是很容易WA和RE,可能得debug很长时间。
值得注意的地方:
1.纸牌被处理的次数中,每次发牌并且检查一次匹配,算处理一次,而不是四次
2.查看匹配的时候,如果一次匹配成功并且删除了三张纸牌,要继续检查是否匹配,这是个循环的过程
3.可以通过用set记录State判重,判断打平的情况
4.纸牌收回手中时,注意纸牌摆放的顺序
#include <bits/stdc++.h>
using namespace std;
int cnt = 0;
deque<int> hand;
vector<deque<int>> tab;
set<vector<deque<int>>> s;
bool input(){
cnt = 0; hand.clear();
while (true){
int x; cin >> x;
if (!x) return false;
hand.push_back(x);
if (hand.size() == 52) return true;
}
}
bool can(int a, int b, int c, deque<int> & cur){
int val1 = a >= 0 ? *(cur.begin() + a) : *(cur.end() + a);
int val2 = b >= 0 ? *(cur.begin() + b) : *(cur.end() + b);
int val3 = c >= 0 ? *(cur.begin() + c) : *(cur.end() + c);
int sum = val1 + val2 + val3;
return sum == 10 || sum == 20 || sum == 30;
}
bool match(deque<int> & cur){
if (can(0, 1, -1, cur)){
int t0 = cur.front(); cur.pop_front();
int t1 = cur.front(); cur.pop_front();
int t_1 = cur.back(); cur.pop_back();
hand.push_back(t0); hand.push_back(t1); hand.push_back(t_1);
return true;
}
if (can(0, -1, -2, cur)){
int t0 = cur.front(); cur.pop_front();
int t_1 = cur.back(); cur.pop_back();
int t_2 = cur.back(); cur.pop_back();
hand.push_back(t0); hand.push_back(t_2); hand.push_back(t_1);
return true;
}
if (can(-1, -2, -3, cur)){
int t_1 = cur.back(); cur.pop_back();
int t_2 = cur.back(); cur.pop_back();
int t_3 = cur.back(); cur.pop_back();
hand.push_back(t_3); hand.push_back(t_2); hand.push_back(t_1);
return true;
}
}
void run(){
tab.clear(); tab.resize(7);
s.clear();
int cur = 0;
while (++cnt, true) {
int x = hand.front(); hand.pop_front();
tab[cur].push_back(x);
while (tab[cur].size() >= 3 && match(tab[cur]));
if (hand.size() == 52) { printf("Win : %d\n", cnt); return; }
if (hand.size() == 0) { printf("Loss: %d\n", cnt); return; }
vector<deque<int>> t(tab); t.push_back(hand);
if (s.count(t)) { printf("Draw: %d\n", cnt); return; }
else s.insert(t);
do {
cur = (cur + 1) % 7;
} while (tab[cur].size() == 0 && cnt >= 8);
}
}
int main()
{
ios::sync_with_stdio(false);
while (input())
run();
return 0;
}