题目:
把52张牌从左到右排好,每张牌自成一个牌堆。当某张牌与它左边那张牌或者左边第三张牌匹配时(花色或者点数相同)时,就把这张牌移到那张牌上面。
移动之后还要查看是否可以进行其他移动。只有位于牌堆顶部的牌才能移动或者参与匹配。当牌堆之间出现空隙时要立刻把右边的所有牌堆左移一格来填
补空隙。如果有多张牌可以移动,先移动最左边的那张牌;如果即可以移一格也可以移3格时,移3格。按顺序输入52张牌,输出最后牌堆数以及各牌堆的牌数。
思路:
看完之后知道要用vector和stack来结合解题,但是没有想到erase方法的使用,结果导致代码写的太冗杂。
开52个stack存到vector中,然后按照题目模拟过程。因为移动之后还要判断能否继续移动,那这里就可以结束这次的移动之后跳出这个循环,直接进行下一次
循环就可以了。
代码:
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define MAX 1000000009 #define FRE() freopen("in.txt","r",stdin) #define FRO() freopen("out.txt","w",stdout) using namespace std; typedef long long ll; const int maxn = 200010; int n,m,d[maxn],vis[maxn]; struct Card { char number; char color; Card() {} Card(char n, char c):number(n),color(c) {} }; vector<stack<Card> > pile; void makeString(string str) {//处理字符串,保存所有的牌 //cout<<str<<endl; for(int i = 0; i<str.length(); i+=3) { stack<Card> sta; sta.push(Card(str[i],str[i+1])); pile.push_back(sta); } } bool judge(Card a,Card b) {//判断两张牌是否可以匹配 if(a.color==b.color || a.number==b.number) { return true; } return false; } void solve() { // for(int i = 0; i<52; i++){ // cout<<pile[i].top().number<<pile[i].top().color<<" "; // if(i==25) // cout<<endl; // } // cout<<endl; while(true) { bool ok = false; for(int i=0; i<pile.size(); i++) { if(i-3>=0 && judge(pile[i].top(),pile[i-3].top())) {//移动3格 pile[i-3].push(pile[i].top()); pile[i].pop(); ok = true; if(pile[i].empty()) { pile.erase(pile.begin()+i); } break; } else if(i-1>=0 && judge(pile[i].top(),pile[i-1].top())) {//移动1格 pile[i-1].push(pile[i].top()); pile[i].pop(); ok = true; if(pile[i].empty()) { pile.erase(pile.begin()+i); } break; } } if(!ok) { break; } } cout<<pile.size(); if(pile.size()==1){ cout<<" pile remaining: 52"<<endl; }else{ cout<<" piles remaining:"; for(int i=0; i<pile.size(); i++){ cout<<" "<<pile[i].size(); } cout<<endl; } } int main() { //FRE(); string str; while(true) { pile.clear(); int idx=1; getline(cin,str); if(str=="#") { break; } makeString(str); getline(cin,str); makeString(str); solve(); } return 0; }