首页 > 其他分享 >CSP模拟-17

CSP模拟-17

时间:2023-08-10 16:37:11浏览次数:33  
标签:cnt ch 匹配 17 010 001 ans CSP 模拟

前言

仔细想了想,考试的时候其实对正解有些思路,但自己认为正确性有问题,所以没这么写,大寄,考了倒2,呜呜呜┭┮﹏┭┮

T1 弹珠游戏

下面的匹配的含义: \(R\) 的匹配指 \(G,B\),其中 \(R\) 为被匹配字母,\(G,B\)为匹配字母;\(G\) 的匹配指 \(R,B\) 以此类推。

我们用把每个人现在手里的牌用十进制来表示。有 \(R\) 的用 \(100\) 表示,有 \(G\) 的用 \(010\) 表示,有 \(B\) 的用 \(001\) 表示。考虑贪心,我们从前往后枚举,先确定一个点,在后面我们若枚举到与之匹配的两个点,那我们直接拿走被匹配的字母和匹配字母,用乘法原理乘上,不再管它这一组。具体请看代码实现。

正确性证明:若我们的 \(R\) 在位置 \(1,3\), \(G\) 在位置 \(2,4\),\(B\) 在位置 \(5,6\)。此时若我们固定两个 \(R\),则找到位置 \(5\) 时发现第一个匹配,我们这时可以将找到的匹配给两个位置 \(1,3\) 的 \(R\),那我们这时该给谁呢?两个都行,因为我们 \(R\) 的所有匹配的位置是一定确定的,我们可以将题目的所有人的不满意之和列出式子

\[\sum (posr-posl) \]

化简:

\[\sum posr - \sum posl \]

其中 \(posr\) 表示匹配的右边字母的位置,\(posl\) 表示被匹配的左边字母的位置。

如果我们都能选的话,按先前的说法为什么将匹配给先出现的被匹配字母??这就涉及到了代码实现。我们有如下代码

		if (num[i] == 100) {
			if (cnt[011]) {
				ans = (ans * cnt[011]) % mod;
				cnt[111] ++;
				cnt[011] --;
			}
			else if (cnt[010]) {
				//这里面不会出现cnt[010]和cnt[001]都存在值得情况
				//因为存在cnt[001]或cnt[010]的一定会并到cnt[010]或cnt[001]里面成为cnt[011] 
=				ans = (ans * cnt[010]) % mod;
				cnt[110] ++;
				cnt[010] --;
			}
			else if (cnt[001]) {
				ans = (ans * cnt[001]) % mod;
				cnt[101] ++;
				cnt[001] --;
			}
			if (cnt[000]) {
				ans = (ans * cnt[000]) % mod;
				cnt[100] ++;
				cnt[000] --;
			}
		}

其中 \(i\) 表示枚举到了第 \(i\) 位。我们为什么要先加匹配字母是两个的??

首先,由于我们推导了上面的式子,所以我们可以发现拿最后一个匹配的时候先拿哪个 \(posr\) 所代表的匹配并不会影响我们的不满意度之和,但我们如果将现在的珠子给只存在一个匹配的人,我们此时最后一个拿的珠子的位置就不再是我们原先 \(posl\) 里面对应的 \(posr\) 了。如:若我们拿的顺序是 \(R,G,B\),如果在拿完 \(R\) 后拿 \(B\) 肯定是不对的。

所以就能得到代码蜡

#include <iostream>
#include <cstdio> 
#include <algorithm>
#include <cmath>
#include <cstring>

using namespace std;
typedef long long ll;
const ll mod = 998244353;

int n;
char ch[1100000];
ll cnt[3000], ans = 1, num[1100000];

int main() {
	scanf("%d", &n);
    ch[1] = getchar();
    while (ch[1] != 'R' && ch[1] != 'B' && ch[1] != 'G') {
        ch[1] = getchar();
    }
    for (int i = 2; i <= n * 3; ++ i) {
        ch[i] = getchar();
    }
    for (int i = 1; i <= n * 3; ++ i) {
    	if (ch[i] == 'R') num[i] = 100;
    	if (ch[i] == 'G') num[i] = 10;
    	if (ch[i] == 'B') num[i] = 1;
	}
	cnt[0] = n;
	for (int i = 1; i <= n * 3; ++ i) {
		if (num[i] == 100) {
			if (cnt[011]) {
				ans = (ans * cnt[011]) % mod;
				cnt[111] ++;
				cnt[011] --;
			}
			else if (cnt[010]) {
				//这里面不会出现cnt[010]和cnt[001]都存在值得情况
				//因为存在cnt[001]或cnt[010]的一定会并到cnt[010]或cnt[001]里面成为cnt[011] 
				ans = (ans * cnt[010]) % mod;
				cnt[110] ++;
				cnt[010] --;
			}
			else if (cnt[001]) {
				ans = (ans * cnt[001]) % mod;
				cnt[101] ++;
				cnt[001] --;
			}
			if (cnt[000]) {
				ans = (ans * cnt[000]) % mod;
				cnt[100] ++;
				cnt[000] --;
			}
		}
		else if (num[i] == 10) {
			if (cnt[101]) {
				ans = (ans * cnt[101]) % mod;
				cnt[111] ++;
				cnt[101] --;
			}
			else if (cnt[100]) {
				ans = (ans * cnt[100]) % mod;
				cnt[110] ++;
				cnt[100] --;
			}
			else if (cnt[001]) {
				ans = (ans * cnt[001]) % mod;
				cnt[011] ++;
				cnt[001] --;
			}
			else {
				ans = (ans * cnt[000]) % mod;
				cnt[010] ++;
				cnt[000] --;
			}
		}
		else if (num[i] == 1) {
			if (cnt[110]) {
				ans = (ans * cnt[110]) % mod;
				cnt[111] ++;
				cnt[110] --;
			}
			else if (cnt[010]) {
				ans = (ans * cnt[010]) % mod;
				cnt[011] ++;
				cnt[010] --;
			}
			else if (cnt[100]) {
				ans = (ans * cnt[100]) % mod;
				cnt[101] ++;
				cnt[100] --;
			}
			else {
				ans = (ans * cnt[000]) % mod;
				cnt[001] ++;
				cnt[000] --;
			}
		}
	}
	cout << ans << endl;
	return 0;
}

标签:cnt,ch,匹配,17,010,001,ans,CSP,模拟
From: https://www.cnblogs.com/jueqingfeng/p/17620704.html

相关文章

  • 23 暑假友谊赛 No.4(UKIEPC 2017)
    23暑假友谊赛No.4(UKIEPC2017)ProblemAAlienSunsethh,开始一眼差分,但是写寄了qwq,后来换枚举过了(Orz,但是看学长差分是能做的,我就说嘛,差分肯定能做(说下枚举思路吧,就是把每个区间都存起来,选出自转周期的最大值为\(ma\),然后去枚举\(0\simma\times1825\),每次看......
  • Audition Au 2017音频编辑软件下载和安装教程
    Audition是一款完善的工具集,其中包含用于创建、混合、编辑和复原音频内容的多轨、波形和光谱显示功能。这一强大的音频工作站旨在加快视频制作工作流程和音频修整的速度,并且还提供带有纯净声音的精美混音效果。软件介绍新机载体验为新用户提供了常见任务的一系列指导解决方法,例如......
  • CLO Standalone 7(3D服装设计软件) v7.1.178.42210 (x64)中文永久使用
    CLOStandalone7是一款专业的3D服装设计软件,它为服装设计师和制造商提供了先进的工具和功能,以快速而准确地创建、模拟和可视化服装设计。点击获取CLOStandalone7 CLOStandalone7具有以下主要特点和功能:三维虚拟设计:CLOStandalone7使用先进的三维建模技术,可以在虚拟......
  • UKIEPC 2017
    A-AlienSunset这到题,用一个数组表示当前时间有多少个星球是夜晚,这样就转换成了区间修改单点查询。因为只查询一次,所以用差分即可。#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintm=1825*100+5;int32_tmain(){ios::sync_wi......
  • LeetCode从算法到算命—1749.任意子数组和的绝对值的最大值
    1749.任意子数组和的绝对值的最大值题目信息给你一个整数数组nums。一个子数组[numsl,numsl+1,...,numsr-1,numsr]的和的绝对值为abs(numsl+numsl+1+...+numsr-1+numsr)。请你找出nums中和的绝对值最大的任意子数组(可能为空),并返回该最大值。abs(x)......
  • Centos安装node-v17
    https://nodejs.org/download/release/v17.9.1/ #切换到统一的安装目录cd/usr/local/src#下载文件wgethttps://nodejs.org/download/release/v17.9.1/node-v17.9.1-linux-x64.tar.xz#解压tar-xJfnode-v17.9.1-linux-x64.tar.xz#将解压文件移动到对应目录下mvn......
  • 堆优化模拟退火(List-Based Simulated Annealing|List-Based SA|LBSA|模拟退火) 算法
    堆优化模拟退火(List-BasedSimulatedAnnealing)算法引入堆优化模拟退火(List-BasedSimulatedAnnealing,简称LBSA)是一种对模拟退火的优化算法。由Shi-huaZhan,[1],[2]JuanLin,[1:1]Ze-junZhang,[1:2]Yi-wenZhong[1:3],[2:1]提出。(以下我们以求最小值为例)解释我们......
  • vs2017 启用自带 反编译功能
    打开此功能后,我们就可以查看dll文件源码了vs2017需要手动打开设置-选项vs2022已经默认打开了,不需要我们单独设置 ......
  • MuMu模拟器运行一段时间后Device.Present耗时突然上升
    1)MuMu模拟器运行一段时间后Device.Present耗时突然上升2)​如何在运行过程中获得温度信息3)InputSystem鼠标更换主按键的Bug4)如何禁止Unity向https://config.uca.cloud.unity3d.com发送设备信息这是第347篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子......
  • 2023年CSPM-3国标项目管理中级认证报名到这里就对了
    CSPM-3中级项目管理专业人员评价,是中国标准化协会(全国项目管理标准化技术委员会秘书处),面向社会开展项目管理专业人员能力的等级证书。旨在构建多层次从业人员培养培训体系,建立健全人才职业能力评价和激励机制的要求,培养我国项目管理领域复合型人才。  【证书含金量】 ·竞聘优先......