hiho 1830(2018 北京网络赛 C) - 模拟

本文深入解析了一种基于扑克游戏的策略算法,详细介绍了四种玩家(play1至play4)的出牌逻辑和挑战规则,包括如何根据手中牌的等级和数量进行最优决策,以及在特定条件下如何挑战其他玩家。通过具体的代码实现,展示了算法的具体运作过程。

题目链接:点击这里

 

解题思路:

play1 : 按相应等级出一张,不能的话只能说谎且出字典序最小的一张.

挑战1: 陈述者出的rank为X的牌数为p,play1手里rank为X的牌为q,q+p>4,挑战陈述者.

挑战2:下一个陈述者是play1且play1下次陈述必须说谎,挑战陈述者

 

paly2:出完手上相应等级的牌,不能的话只能说谎且出字典序最小的一张

挑战1:下一个陈述者是play2且play2下次陈述必须说谎,挑战陈述者

 

play3:出完手上相应等级的牌,不能的话只能说谎且出完手上数量最小的那个rank,如果有多个选择,选字典序小的那个.

挑战1::play3手上有4张当前陈述者的rank.挑战陈述者

 

play4:如果手上有相应rank的牌3张或者4张,出完该rank牌,不能的话只能说谎且出完相应rank的牌加上一张字典序最小的一张(如果有的话)

挑战1::当陈述者清空了手上的牌时,挑战陈述者

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
const int mx = 1e3+10;
const int a[] = {9,1,2,3,4,5,6,7,8,0,10,12,11};//字典序 
int n,m,rem[20];
int cnt[6][20];
char str[10];
int Get(){
	if(str[0] == 'A')return 0;
	if(str[0] == 'J')return 10;
	if(str[0] == 'Q')return 11;
	if(str[0] == 'K')return 12;
	if(str[0] == '1')return 9;
	return (int)(str[0]-'0'-1);
}
void input(int x){
	if(x==0) putchar('A');
	else if(x>=1&&x<=8) putchar(x+'0'+1);
	else if(x==9) printf("10");
	else if(x==10) putchar('J');
	else if(x==11) putchar('Q');
	else putchar('K');
	putchar(' ');
}
bool cut(int H)//减去一张字典序最小的牌 
{
	for(int i=0;i<13;i++)
	if(cnt[H][a[i]]){
		cnt[H][a[i]]--;
		rem[a[i]]++;			
		return 1; 
	}	
	return 0;
}
pair<int,int> down(int H,int beg,int v1)
{
	if(cnt[H][beg]){
		if(v1){
			cnt[H][beg]--,rem[beg]++;
			return make_pair(1,1);
		}else{
			rem[beg] += cnt[H][beg];
			int v = cnt[H][beg];
			cnt[H][beg] = 0;
			return make_pair(1,v);
		}
	}else{
		cut(H);
		return make_pair(0,1);
	}
}
pair<int,int> Put(int H,int beg)//相应的出牌规则 
{
	if(H<2) return down(H,beg,H^1);
	else if(H==2){
		if(cnt[H][beg]){
			rem[beg] += cnt[H][beg];
			int v = cnt[H][beg];
			cnt[H][beg] = 0;
			return make_pair(1,v);
		}else{
			int mi = 100,p;
			for(int i=0;i<13;i++)
			if(cnt[H][a[i]]&&mi>cnt[H][a[i]]) mi = cnt[H][a[i]],p = a[i];
			
			rem[p] += cnt[H][p];
			int v = cnt[H][p];
			return make_pair(cnt[H][p] = 0,v);
		}
	}else{
		rem[beg] += cnt[H][beg];
		int v = cnt[H][beg];
		cnt[H][beg] = 0;	
		if(v<3&&cut(H)) return make_pair(0,v+1);
		return make_pair(1,v);
	}
}
bool empty(int H)
{
	for(int i=0;i<13;i++)
	if(cnt[H][i]) return 0;
	return 1;
}
bool check(int x,int H,int beg,int v)//是否挑战 
{
	if(x==0){
		if(v+cnt[x][beg]>4) return 1;
		if((H+1)%4==x&&cnt[x][(beg+1)%13]==0) return 1;
	}else if(x==1){
		if((H+1)%4==x&&cnt[x][(beg+1)%13]==0) return 1;
	}else if(x==2){
		if(cnt[x][beg]==4) return 1;
	}else{
		if(empty(H)) return 1;
	}
	return 0;
}
int solve()
{
	int H = 0,beg = 0;
	while(1){
		pair<int,int> pa = Put(H,beg);
		for(int i=0;i<4;i++)
		if(i!=H&&check(i,H,beg,pa.se)){
			int g = pa.fi? i:H;//收回桌上的牌 
			for(int j=0;j<13;j++) cnt[g][j] += rem[j],rem[j] = 0; 
			break;
		}
		if(empty(H)) return H;
		H = (H+1)%4,beg = (beg+1)%13;
	}
}
int main()
{
	while(~scanf("%s",str))
	{
		memset(cnt,0,sizeof(cnt));
		memset(rem,0,sizeof(rem));
		cnt[0][Get()]++;
		for(int i=0;i<12;i++){
			scanf("%s",str);
			cnt[0][Get()]++;
		}
		for(int i=1;i<=3;i++){
			for(int j=1;j<=13;j++){
				scanf("%s",str);
				cnt[i][Get()]++;
			}
		}
		int ans = solve();
		for(int i=0;i<4;i++){
			if(ans==i) puts("WINNER");
			else{
				for(int j=0;j<13;j++)
				while(cnt[i][j]--) input(j);
				puts("");
			}
		}
	}
	return 0;
}

 

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值