首页 > 其他分享 >『模拟赛』暑假集训CSP提高模拟1

『模拟赛』暑假集训CSP提高模拟1

时间:2024-07-18 19:56:12浏览次数:12  
标签:cnt 集训 int double bnum else CSP 模拟 anum

Rank

感冒了,同时心情极差,状态不好ww

image

A. Start

打磨你。

T1 放大模拟还是过于抽象了,开局劝退,遂倒序开题。

赛时想复杂了一点,开了两个二维数组存牌,同时存 double 状态时也出了问题,还没有考虑负数的向下取整。我太蒻了

改后虽然还是 300 多行,但是思路起码清晰了很多,改了几个小错就 A 了。

Code:
const int N=3e5+5;
const int mod=1e9+7;
int n,m,k,p,tot=1;
// tot 为牌堆摸取位置
string nam[6],have[6][4],paidui[N];
// 玩家名,玩家拥有手牌,牌堆
bool turnn,doubll,jp,endd;
// 分别表示出牌顺序,double 施加情况,解牌跳过 double,结束回合
// 由于 double 无论如何都是施加在下一个出牌的人身上的,所以一个变量就够
bool cmp(string a,string b)// 无 double 优先级排序
{
	int anum=-1,bnum=-1;
	if(a=="C2") anum=0;
	else if(a=="A99") anum=1;
	else if(a=="A49") anum=2;
	else if(a=="A19") anum=3;
	else if(a=="A9") anum=4;
	else if(a=="A5") anum=5;
	else if(a=="A2") anum=6;
	else if(a=="A1") anum=7;
	else if(a=="B1") anum=8;
	else if(a=="B9") anum=9;
	else if(a=="B19") anum=10;
	else if(a=="D2") anum=11;
	else if(a=="E99") anum=12;
	else if(a=="E49") anum=13;
	else if(a=="E0") anum=14;
	else if(a=="PASS") anum=15;
	else if(a=="TURN") anum=16;
	else if(a=="DOUBLE") anum=17;
	if(b=="C2") bnum=0;
	else if(b=="A99") bnum=1;
	else if(b=="A49") bnum=2;
	else if(b=="A19") bnum=3;
	else if(b=="A9") bnum=4;
	else if(b=="A5") bnum=5;
	else if(b=="A2") bnum=6;
	else if(b=="A1") bnum=7;
	else if(b=="B1") bnum=8;
	else if(b=="B9") bnum=9;
	else if(b=="B19") bnum=10;
	else if(b=="D2") bnum=11;
	else if(b=="E99") bnum=12;
	else if(b=="E49") bnum=13;
	else if(b=="E0") bnum=14;
	else if(b=="PASS") bnum=15;
	else if(b=="TURN") bnum=16;
	else if(b=="DOUBLE") bnum=17;
	return anum<bnum;
}
bool cmpd(string a,string b)// 有 double 优先级排序
{
	int anum=-1,bnum=-1;
	if(a=="PASS") anum=0;
	else if(a=="TURN") anum=1;
	else if(a=="DOUBLE") anum=2;
	else if(a=="D2") anum=3;
	else if(a=="B19") anum=4;
	else if(a=="B9") anum=5;
	else if(a=="B1") anum=6;
	else if(a=="A1") anum=7;
	else if(a=="A2") anum=8;
	else if(a=="A5") anum=9;
	else if(a=="A9") anum=10;
	else if(a=="A19") anum=11;
	else if(a=="A49") anum=12;
	else if(a=="A99") anum=13;
	else if(a=="C2") anum=14;
	else if(a=="E0") anum=15;
	else if(a=="E49") anum=16;
	else if(a=="E99") anum=17;
	if(b=="PASS") bnum=0;
	else if(b=="TURN") bnum=1;
	else if(b=="DOUBLE") bnum=2;
	else if(b=="D2") bnum=3;
	else if(b=="B19") bnum=4;
	else if(b=="B9") bnum=5;
	else if(b=="B1") bnum=6;
	else if(b=="A1") bnum=7;
	else if(b=="A2") bnum=8;
	else if(b=="A5") bnum=9;
	else if(b=="A9") bnum=10;
	else if(b=="A19") bnum=11;
	else if(b=="A49") bnum=12;
	else if(b=="A99") bnum=13;
	else if(b=="C2") bnum=14;
	else if(b=="E0") bnum=15;
	else if(b=="E49") bnum=16;
	else if(b=="E99") bnum=17;
	return anum<bnum;
}
// 排序保证选择普通牌顺序
namespace Wisadel
{
	int Wgetnext(int now)
	{// 找到下一个出牌的人
		if(turnn) now=(now==1?n:now-1);
		else now=(now==n?1:now+1);
		return now;
	}
	void Wworkjp(int now)
	{// 解牌优先
		bool can=0;
		sort(have[now]+1,have[now]+4,cmpd);
		// 按 double 优先级排序
		fo(i,1,3)
		{// 先考虑解牌
			string ss=have[now][i];
			if(ss=="PASS")
			{
				cout<<"used "<<ss<<",now p="<<p<<".\n";
				jp=1;can=1;// 直接跳过
				have[now][i]=paidui[tot++];// 取牌
				break;
			}
			else if(ss=="TURN")
			{
				cout<<"used "<<ss<<",now p="<<p<<".\n";
				jp=1;can=1;
				if(turnn) turnn=0;
				else turnn=1;// 反转出牌顺序
				have[now][i]=paidui[tot++];
				break;
			}
			else if(ss=="DOUBLE")
			{
				cout<<"used "<<ss<<",now p="<<p<<".\n";
				jp=1;can=1;
				doubll=1;// 记录 double 效果
				have[now][i]=paidui[tot++];
				break;
			}
		}
		if(can) return;
		// 若无解牌,则考虑基本牌
		int num=0,no,minn=1e9;
		fo(i,1,3)
		{// 考虑基本牌使用,按要求找最小值
			string ss=have[now][i];no=p;
			if(ss=="A1") no+=1;
			else if(ss=="A2") no+=2;
			else if(ss=="A5") no+=5;
			else if(ss=="A9") no+=9;
			else if(ss=="A19") no+=19;
			else if(ss=="A49") no+=49;
			else if(ss=="A99") no+=99;
			else if(ss=="B1") no-=1;
			else if(ss=="B9") no-=9;
			else if(ss=="B19") no-=19;
			else if(ss=="C2") no*=2;
			else if(ss=="D2") no=floor(1.0*no/2);
			else if(ss=="E0") no=0;
			else if(ss=="E49") no=49;
			else if(ss=="E99") no=99;
			else no=10000;
			if(no<=99&&no<minn) num=i,minn=no,can=1;
		}
		if(!can)
		{// 仍必败
			endd=1;
			cout<<"lost the game.\n";
		}
		else
		{// 可不败,打一摸一
			doubll=0;
			cout<<"used "<<have[now][num]<<",now p="<<minn<<".\n";
			have[now][num]=paidui[tot++];
			p=minn;
		}
	}
	void Wwork(int now)
	{// 普通牌优先
		sort(have[now]+1,have[now]+4,cmp);
		// 按无 double 优先级排序
		bool can=0;int num=0,no,maxx=-1e9;
		fo(i,1,3)
		{// 考虑基本牌使用,按要求找范围内最大值
			string ss=have[now][i];no=p;
			if(ss=="A1") no+=1;
			else if(ss=="A2") no+=2;
			else if(ss=="A5") no+=5;
			else if(ss=="A9") no+=9;
			else if(ss=="A19") no+=19;
			else if(ss=="A49") no+=49;
			else if(ss=="A99") no+=99;
			else if(ss=="B1") no-=1;
			else if(ss=="B9") no-=9;
			else if(ss=="B19") no-=19;
			else if(ss=="C2") no*=2;
			else if(ss=="D2") no=floor(1.0*no/2);
			else if(ss=="E0") no=0;
			else if(ss=="E49") no=49;
			else if(ss=="E99") no=99;
			else no=10000;
			if(no<=99&&no>maxx) num=i,maxx=no,can=1;
		}
		if(can)
		{// 能打则打一摸一
			cout<<"used "<<have[now][num]<<",now p="<<maxx<<".\n";
			p=maxx;
			have[now][num]=paidui[tot++];
			return;
		}
		fo(i,1,3)
		{// 否则考虑解牌
			string ss=have[now][i];
			if(ss=="PASS")
			{
				cout<<"used "<<ss<<",now p="<<p<<".\n";
				can=1;
				have[now][i]=paidui[tot++];
				break;
			}
			else if(ss=="TURN")
			{
				cout<<"used "<<ss<<",now p="<<p<<".\n";
				can=1;
				if(turnn) turnn=0;
				else turnn=1;
				have[now][i]=paidui[tot++];
				break;
			}
			else if(ss=="DOUBLE")
			{
				cout<<"used "<<ss<<",now p="<<p<<".\n";
				can=1;doubll=1;
				have[now][i]=paidui[tot++];
				break;
			}// 过程中直接打一摸一
		}
		if(!can)
		{// 必败
			endd=1;
			cout<<"lost the game.\n";
		}
	}
	short main()
	{
		// freopen("A.in","r",stdin),freopen("1.out","w",stdout);
		n=qr,m=qr,k=qr;
		fo(i,1,n) cin>>nam[i]>>have[i][1]>>have[i][2]>>have[i][3];
		fo(i,1,k) cin>>paidui[i];
		// 输入
		int laslos=1;
		// 从上回合熟的人开始,第一回合从 1 号开始
		fo(roundd,1,m)
		{
			printf("Round %d:\n",roundd);
			doubll=p=turnn=endd=0;int now=laslos;
			// 初始化标记变量
			while(1)
			{
				cout<<nam[now]<<' ';jp=0;
				if(doubll)
				{// 有 double 效果
					Wworkjp(now);
					// 先按 double 打一次
					if(jp)
					{// 使用了解牌,直接跳过
						now=Wgetnext(now);
						continue;
					}
					else if(endd)
					{// 败了
						laslos=now;
						if(roundd!=m)
						{// 重新摸牌
							have[now][1]=paidui[tot++];
							have[now][2]=paidui[tot++];
							have[now][3]=paidui[tot++];
						}
						break;
					}
					else 
					{// 否则按无 double 效果再进行一回合
						cout<<nam[now]<<' ';
						Wwork(now);
					}
				}
				else Wwork(now);
				// 无 double 效果
				if(endd)
				{// 败了
					laslos=now;
					if(roundd!=m)
					{
						have[now][1]=paidui[tot++];
						have[now][2]=paidui[tot++];
						have[now][3]=paidui[tot++];
					}
					break;
				}
				now=Wgetnext(now);
			}
		}
		return Ratio;
	}
}
int main(){return Wisadel::main();}

确实又臭又长了属于是。

咕一个长度在 150 行以内的,不无脑压行。


B. Mine

一个简单的 dp,但赛时倒数开的,时间不是很足,在暴搜上耽误很久。

所以以后看见题不能光想着搜了,脑子浑了就打醒之后考虑考虑 dp。

思路挺简单,讲的也很明白,不多写了。

C. 小凯的疑惑

数论题。同样最后开的这道题,压根没去想正解,要不是打 Subtask1 时候暴力摸出来了 Subtask2,这题就保龄了。

其实不互质无解挺显然的,但赛时没看出来,唐了。

然后远古的题考察化简式子化成 \(O(1)\) 的,但由于评测机的更新换代现在 \(10^8\) 的范围 \(O(n)\) 也能过,但还是没想出来。

image

粘一张推导,以后看。

D. 春节十二响

其实一眼泄题了不是吗

一道启发式合并。

题面挺简单的,起码看了 T1 之后这么想。

首先想的是树剖,每条链按类似田忌赛马的思想,最大值放在一起,次大值放在一起,以此类推,答案即为每一堆中最大值的和。

那么发现它是一种合并的思想,最后结果是得到了一条链,答案也就变成了这条链上的点权之和。

实现也不难,把每个父节点向子节点连一条单向边,dfs 到最深然后逐层合并,每条链的头没有对应的点,合并后再加入,链用优先队列维护很方便。

Code:
const int N=4e6+5;
int n;
ll ans;
int a[N],zc[N],id[N],tot;
int hh[N],to[N],ne[N],cnt;
priority_queue<int>q[N];
namespace Wisadel
{
	void Wadd(int u,int v)
	{
		to[++cnt]=v;
		ne[cnt]=hh[u];
		hh[u]=cnt;
	}
	void Wmerge(int x,int y)
	{
		if(q[id[x]].size()<q[id[y]].size()) swap(id[x],id[y]);
		int len=q[id[y]].size();
		fo(i,1,len)
			zc[i]=max(q[id[x]].top(),q[id[y]].top()),
			q[id[x]].pop(),q[id[y]].pop();
		fo(i,1,len) q[id[x]].push(zc[i]);
	}
	void Wdfs(int u)
	{
		id[u]=++tot;
		for(int i=hh[u];i!=-1;i=ne[i])
		{
			int v=to[i];
			Wdfs(v);
			Wmerge(u,v);
		}
		q[id[u]].push(a[u]);
	}
	short main()
	{
		memset(hh,-1,sizeof hh);
		n=qr;int f;
		fo(i,1,n) a[i]=qr;
		fo(i,2,n) f=qr,Wadd(f,i);
		Wdfs(1);
		while(q[id[1]].size()) ans+=q[id[1]].top(),q[id[1]].pop();
		printf("%lld\n",ans);
		return Ratio;
	}
}
int main(){return Wisadel::main();}

完结撒花~

久违了

标签:cnt,集训,int,double,bnum,else,CSP,模拟,anum
From: https://www.cnblogs.com/Ratio-Yinyue1007/p/18310327

相关文章

  • 2024夏令营提高1模考0718模拟赛(提高1)补题报告
    2024夏令营提高1模考0718模拟赛(提高1)补题报告$$0718模拟赛(提高1)\\补题报告\2024年7月18日\by\\\唐一潇$$一、做题情况第一题比赛$100/100$,赛后通过第二题比赛$0/100$,赛后通过第三题比赛$0/100$,赛后通过第四题比赛$0/100$,赛后通过比......
  • 暑假集训CSP提高模拟1
    暑假集训CSP提高模拟1唐完乐!T1Start大模拟,之前还做过。结果照样挂90pts细节较多,比较坑的是除法要向下取整,而/是向\(0\)取整。T2mine这\(DP\)已经简单到不能在简单了。设\(dp_{i,0/1/2}\)表示到第\(i\)位,\(0\)后面不放雷,\(1\)后面放雷,\(2\)自己是雷。......
  • 暑假集训CSP提高模拟1
    暑假集训CSP提高模拟1\(T1\)T2687.Start原题:luoguP7506「Wdsr-2.5」琪露诺的算数游戏大模拟。\(T2\)T807.mine原题:CF404DMinesweeper1D设\(f_{i,0/1/2/3/4}\)分别表示处理到第\(i\)位时,第\(i\)位为雷/第\(i\)位不为雷,第\(i-1,i+1\)位不为雷/第\(......
  • [Xamarin] 在 Visual Studio 中使用 adb 连接本机 Mumu 模拟器
    官网https://mumu.163.com/操作步骤1.开启Mumu模拟器的【开发者模式】模式。2.在【问题诊断】中查看ADB端口号3.在VisualStudio中找到"Tools/Android/AndroidAdbCommandPrompt"4.使用命令监听端口adbtcpip163845.使用命令建立连接adbconn......
  • 【比赛】暑假集训CSP提高模拟1
    T1Start10Pts题面(较长)大模拟。点击查看代码#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintinf=INT_MAX;stringnm[10]={"","D","B","A","C","E","PASS","......
  • 玄机——第九章-blueteam 的小心思 wp(HVV——“蓝队”应急响应简单模拟例题)
    文章目录一、前言二、概览简介三、参考文章四、步骤(解析)准备步骤#1.0步骤#1.1攻击者通过什么密码成功登录了网站的后台?提交密码字符串的小写md5值,格式flag{md5}。步骤#1.2攻击者在哪个PHP页面中成功上传了后门文件?例如upload.php页面,上传字符串"upload.php"的小写md5值......
  • 2023HACSP-J补测
    都快忘了自己还打过这个比赛了,所以来补一下。完整题目在这里查看。Day0来到郑州,寻找考场。幸好提前来了,因为考场大门就5m宽(HA用不用这么穷啊喂,来JZYZ不好么),开车转了20min才找到。旅馆离考场很近,走路就能到。和zjyDALAO住隔壁,晚上去他那里写了一会题就去睡了。Day1早上......
  • vector的模拟实现
    目录构造函数,初始化列表析构函数长度空间迭代器扩容尾插 []的模拟实现insert的模拟实现erase的模拟实现尾删resize的模拟实现深拷贝模拟,vectorv1(v)swap的模拟实现=的模拟实现vectorv(10,1)支持多样类型的迭代器text总代码开头 #include<iostream>#i......
  • 第十五届蓝桥杯单片机模拟考试实战题目
    目录一、硬件框图二、功能描述2.1基本功能描述2.2显示功能1.测距界面2.参数界面3.记录界面4.显示要求2.3按键功能2.4旋钮模式2.5LED指示灯功能2.6初始状态三、代码实现1>主函数:2>测距驱动函数3>PCF8591驱动函数4>矩阵按键驱动函数5>CT107D头文件四、题目链......
  • 2024 暑假集训杂题选做
    目录写在前面CF1981DCF1992F写在最后写在前面我是飞物。CF1981D2400妈的好诡异的题场上拿到这题我都不知道我要干啥呃呃考虑到每个合数均为若干质数的乘积,则若构造方案中有合数,可以将合数替换为质数从而减少使用的权值的种类数,于是仅需考虑使用质数构造,则此时并不需要考虑具......