「题解」卡 ka

本文将同步发布于:

题目

题意简述

给定两个人的牌组,其中一个人叫 roland,他的策略是:对方弃权,我出的牌越多越好;对方出牌,我出能管住的最少的牌。

可以出的类型为:顺子、炸弹、三张牌、对子(两张牌)、单张牌。

另一个人叫 oldman,他全知全能,采用最优策略。他想知道,结局时 roland 的牌数减 oldman 的牌数最多是多少。

题解

简单搜索

直接按照策略模拟即可。

参考程序

#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define reg register
typedef long long ll;

bool st;

inline int read(void){
	reg char ch=getchar();
	reg int res=0;
	while(!isdigit(ch)) ch=getchar();
	while(isdigit(ch)) res=10*res+(ch^'0'),ch=getchar();
	return res;
}

inline int min(reg int a,reg int b){
	return a<b?a:b;
}

int n,m;

struct Node{
	int cnt,lim;
	inline Node(reg int cnt=0,reg int lim=0):cnt(cnt),lim(lim){
		return;
	}
};

inline int mod(reg int x){
	if(x<0)
		return x+13;
	else
		return x;
}

struct State{
	int _sum,cnt[13];
	//0 1 2 3 4 5 6 7 8 9 0 1 2
	//3 4 5 6 7 8 9 0 J Q K A 2
	inline State(void){
		memset(cnt,0,sizeof(cnt));
		return;
	}
	inline int sum(void)const{
		return _sum;
	}
	inline bool empty(void)const{
		return !_sum;
	}
	inline bool check(const Node& a)const{
		if(a.cnt>=5){
			if(a.lim+a.cnt-1>11)
				return false;
			for(reg int i=0;i<a.cnt;++i)
				if(!cnt[mod(i+a.lim)])
					return false;
			return true;
		}
		else
			return cnt[a.lim]>=a.cnt;
	}
	inline State chg(const Node& a)const{
		State res=*this;
		res._sum-=a.cnt;
		if(a.cnt>=5)
			for(reg int i=0;i<a.cnt;++i)
				--res.cnt[mod(i+a.lim)];
		else
			res.cnt[a.lim]-=a.cnt;
		return res;
	}
};

/*
inline void print(State x){
	printf("3 4 5 6 7 8 9 0 J Q K A 2\n");
	for(reg int i=0;i<13;++i)
		printf("%d ",x.cnt[i]);
	puts("");
	return;
}
*/

const int inf=1e9;

inline bool check(const Node& a,const Node& b){
	//assert(a.cnt);
	if(b.cnt==0)
		return true;
	else if(a.cnt==4)
		if(b.cnt!=4)
			return true;
		else
			return a.lim>b.lim;
	else if(b.cnt==4)
		return false;
	else if(a.cnt!=b.cnt)
		return false;
	else
		return a.lim>b.lim;
}

int ans;

inline void dfs(reg bool opt,State oldman,State roland,const Node& las){
	/*
	printf("opt=%d\n",opt);
	print(oldman),print(roland);
	printf("las=(%d,%d)\n",las.cnt,las.lim);
	puts("================");
	*/
	if(roland.sum()<=ans)
		return;
	if(oldman.empty()||roland.empty()){
		ans=max(ans,roland.sum()-oldman.sum());
		return;
	}
	if(opt){ //roland
		if(!las.cnt)
			for(reg int i=roland.sum();i>=1;--i)
				for(reg int j=(i>=5)?-2:0;j<13;++j){
					if(roland.check(Node(i,j))&&check(Node(i,j),las))
						return dfs(!opt,oldman,roland.chg(Node(i,j)),Node(i,j));
				}
		else{
			for(reg int i=3;i>=1;--i)
				for(reg int j=0;j<13;++j)
					if(roland.check(Node(i,j))&&check(Node(i,j),las))
						return dfs(!opt,oldman,roland.chg(Node(i,j)),Node(i,j));
			for(reg int i=roland.sum();i>=4;--i)
				for(reg int j=(i>=5)?-2:0;j<13;++j)
					if(roland.check(Node(i,j))&&check(Node(i,j),las))
						return dfs(!opt,oldman,roland.chg(Node(i,j)),Node(i,j));
			return dfs(!opt,oldman,roland,Node(0,0));
		}
	}
	else{ //oldman
		for(reg int i=oldman.sum();i>=1;--i)
			for(reg int j=(i>=5)?-2:0;j<13;++j)
				if(oldman.check(Node(i,j))&&check(Node(i,j),las))
					dfs(!opt,oldman.chg(Node(i,j)),roland,Node(i,j));
		dfs(!opt,oldman,roland,Node(0,0));
	}
	return;
}

bool ed;

int main(void){
	while(n=read(),m=read(),n|m){
		State oldman,roland;
		oldman._sum=n,roland._sum=m;
		for(reg int i=1;i<=n;++i){
			static char opt;
			do
				opt=getchar();
			while(!isalnum(opt));
			switch(opt){
				case '3' ... '9':++oldman.cnt[opt-'3'];break;
				case '1':++oldman.cnt[7];cin>>opt;break;
				case 'J':++oldman.cnt[8];break;
				case 'Q':++oldman.cnt[9];break;
				case 'K':++oldman.cnt[10];break;
				case 'A':++oldman.cnt[11];break;
				case '2':++oldman.cnt[12];break;
			}
		}
		for(reg int i=1;i<=m;++i){
			static char opt;
			do
				opt=getchar();
			while(!isalnum(opt));
			switch(opt){
				case '3' ... '9':++roland.cnt[opt-'3'];break;
				case '1':++roland.cnt[7];cin>>opt;break;
				case 'J':++roland.cnt[8];break;
				case 'Q':++roland.cnt[9];break;
				case 'K':++roland.cnt[10];break;
				case 'A':++roland.cnt[11];break;
				case '2':++roland.cnt[12];break;
			}
		}
		ans=-inf;
		dfs(0,oldman,roland,Node(0,0));
		if(ans>0)
			printf("Lose\n%d\n",ans);
		else
			printf("Win\n%d\n",-ans);
	}
	fprintf(stderr,"%.3lf s\n",1.0*clock()/CLOCKS_PER_SEC);
	fprintf(stderr,"%.3lf MiB\n",(&ed-&st)/1048576.0);
	return 0;
}
上一篇:Adobe illustrator/Ai 2019 软件安装包(附安装教程)


下一篇:「日记」八月五