题目描述
如原题
算法
模拟
这道题利用模拟就能搞定,有几个需要注意的点:
1. 取数据是从牌堆第一个取,而不是最后一个
2. 翻开后的牌,不能被再取(取的牌需要是背面朝上)。所以其实可以拿数组记录一下该牌堆翻开的牌有几张。
3. 牌面数字会对应下标,所以注意下标的取值。
时间复杂度分析:平均下来应该是$O(N)$吧,最差的情况每一堆牌每一张都翻过来了。
因为13
堆要从顶部取,其他堆要从底部,所以干脆就用了list
,改成deque
之后运行时间小了1ms
.
C++ 代码
#include<bits/stdc++.h>
#include<list>
using namespace std;
int main(){
vector<list<int>> heaps(14);
vector<int> ucnt(14, 0); //正面向上的牌的数量
for(int i=1;i<=13;i++){
list<int> temp;
char c;
for(int j=0;j<4;j++){
cin>>c;
if(c=='0') temp.push_back(10);
else if(c=='J') temp.push_back(11);
else if(c=='Q') temp.push_back(12);
else if(c=='K') temp.push_back(13);
else if(c=='A') temp.push_back(1);
else temp.push_back(c-'0');
}
heaps[i] = temp;
}
int life = 4;
while(life > 0){
// draw from life heap
int card = heaps[13].front();
heaps[13].pop_front();
while(card != 13) { // loop operation before 'K' appear
int t = card;
ucnt[t]++; // increase card
card = heaps[t].back();
// heaps[card].pop_back(); // 这里card已经被更新了!!!
heaps[t].pop_back(); // 弹出的应该是之前的card=t
}
life--; // die if card = 'K'
}
int ans = 0;
for(int i=1;i<=12;i++){
if(ucnt[i]==4) ans++;
}
cout<<ans<<endl;
return 0;
}
刚刚发现我这代码其实有个bug,但是_本题没有相应的case_。也就是说,初始时候如果4张就已经一样了,我的
ucnt[i]=0
。这个返回显然是不对的。
A A A A
...
8 8 8 8