题解:[NOIP 2015 提高组] 斗地主
题意分析
爆搜即可。
优先出顺子、带牌,剩下的散排无论几张,一类牌都可以一次出完。
一个坑点:一定不要使用 else if,我因为这个导致某些操作不会被判断。
AC 代码
//#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<ctime>
#include<deque>
#include<queue>
#include<stack>
#include<list>
#include<random>
using namespace std;
constexpr const int N=23,V=15;
constexpr const int length[4]={0,5,3,2};
mt19937 Rand(time(0));
int cnt[V+1];
int translate(int a,int b){
if(3<=a&&a<=13){
return a-2;
}else if(a==1){
return 12;
}else if(a==2){
return 13;
}else{
if(b==1){
return 14;
}else{
return 15;
}
}
}
bool check(){
for(int i=1;i<=V;i++){
if(cnt[i]){
return false;
}
}
return true;
}
int ans=2147483647;
void dfs(int step){
if(step>=ans){
return;
}
if(check()){
ans=step;
return;
}
for(int i=1;i<=3;i++){
int pl=0;
for(int j=1;j<=12;j++){
if(cnt[j]>=i){
pl++;
//顺子[j-pl+1,j]
if(pl>=length[i]){
for(int k=j-pl+1;k<=j;k++){
cnt[k]-=i;
}
dfs(step+1);
for(int k=j-pl+1;k<=j;k++){
cnt[k]+=i;
}
}
}else{
pl=0;
}
}
}
//三带二/一
for(int i=1;i<=V;i++){
if(cnt[i]>=3){
cnt[i]-=3;
for(int j=1;j<=V;j++){
if(cnt[j]){
cnt[j]--;
dfs(step+1);
cnt[j]++;
}
if(cnt[j]>=2){
cnt[j]-=2;
dfs(step+1);
cnt[j]+=2;
}
}
cnt[i]+=3;
}
}
//四带二/四
for(int i=1;i<=V;i++){
if(cnt[i]>=4){
cnt[i]-=4;
for(int j=1;j<=V;j++){
if(cnt[j]>=2){
cnt[j]-=2;
for(int k=1;k<=V;k++){
if(cnt[k]>=2){
cnt[k]-=2;
dfs(step+1);
cnt[k]+=2;
}
}
cnt[j]+=2;
}
if(cnt[j]){
cnt[j]--;
for(int k=1;k<=V;k++){
if(cnt[k]){
cnt[k]--;
dfs(step+1);
cnt[k]++;
}
}
cnt[j]++;
}
}
cnt[i]+=4;
}
}
for(int i=1;i<=V;i++){
if(cnt[i]){
step++;
}
}
//火箭
if(cnt[14]&&cnt[15]){
step--;
}
ans=min(ans,step);
}
int main(){
/*freopen("test.in","r",stdin);
freopen("test.out","w",stdout);*/
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int T,n;
cin>>T>>n;
while(T--){
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;i++){
int a,b;
cin>>a>>b;
cnt[translate(a,b)]++;
}
ans=2147483647;
dfs(0);
cout<<ans<<'\n';
}
/*fclose(stdin);
fclose(stdout);*/
return 0;
}

浙公网安备 33010602011771号