I Pa?sWorD

2023icpc网络赛第一场 I

题意:题目给出只包含大小写字母,数字以及'?'的字符串,对于每一个小写字母,这一位字符既有可能是该小写字母,也有可能是该小写字母的对应大写字母,也就是该位的字符有两种可能,对于问号,可能是所有大写字母或者所有小写字母,或者所有单数字,则共有62种情况,而对于大写字母和数字位则都是确定的只有这一种情况

要求输出最后符合以下条件的字符串共有多少种

1、至少有一个小写字母

2、至少有一个大写字母

3、至少有一个数字位

4、相邻的两个字符不能相同

思路:容斥原理+线性dp

我们暂且先不管前三个要求,对于要求4,可以通过线性dp来解决,我们定义dp[i][j]为以第i位为结尾并且结尾这一位选择j(定义1-26代表大写字母,27-52为小写字母,53-62为数字位,63代表该位的所有情况的总和,63最后单独处理)共有多少种情况,则对于某一位选某一个字符的情况数即为前一位的总情况数减去前一位也选相同字符的情况数,则有状态转移方程:

dp[i][j]=dp[i-1][63]-dp[i-1][j]

然而题目中给出了对于内存的限制,通过观察不难发现每一次状态更新只与前一层有关,所以考虑将dp数组降维

此时我们再来解决前三个条件,对于之前提到的线性dp,我们可以得到在不考虑大小写字母以及数字位是否都存在的所有符合条件4的合法情况数,但其中是存在违反条件1-3的情况的,我们现在要做的是将这些情况不重不漏(划重点)的减去,这样我们就可以得到最终结果,这时就要应用到容斥原理:

我们将这些情况(已知所有符合条件4的情况中违反条件1-3的所有情况)抽象成以下图形,其中圈1为一定不包括大写字母的所有情况,圈2为一定不包括小写字母的所有情况,圈3为一定不包括数字位的所有情况,那么现在问题就是要求出这三个圆的共同覆盖面积并减去,

这时我们通过规定是否一定不存在大写字母、小写字母或者数字位对线性dp进行限制并求得在该条件下的情况数,具体实现方式见代码

而当我们分别减去一定不存在大写字母,一定不存在小写字母,一定不存在数字位这三种情况的方案数之后,对于该图形中的每个小图形具体减了几次见下图

这时我们又发现中间有一部分多减了,所以我们又要将部分图形给加回来,此时我们发现可以通过加每两个圆的公共部分来将结果进一步推进,对于一定不存在大写字母并且一定不存在数字位的图形范围为:

将三个圆的两两公共部分都加回来之后对于每个小图形的减去次数可表示为:

此时我们不难发现只需要将三种字符都一定不存在的情况减去就可以了(实际上这部分根本不存在,所以减不减无所谓)

最后的效果:

ac代码:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define INF 0x3f3f3f3f
#define pb push_back
#define int long long
// #define int unsigned long long
#define Mirai ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
typedef pair<int,int> pii;
const int N=1e5+10,mod=998244353;
int dp[2][100];//1-26 大写字母 27-52 小写字母 53-62 数字 63 总和
int b[3];
int n;
string s;
int get()
{memset(dp,0,sizeof dp);dp[0][63]=1;for(int i=1;i<=n;i++){for(int j=1;j<=63;j++)dp[i&1][j]=0;if(s[i]>='A'&&s[i]<='Z')//大写{if(b[0])return 0;dp[i&1][s[i]-'A'+1]=dp[(i-1)&1][63]-dp[(i-1)&1][s[i]-'A'+1];}else if(s[i]>='0'&&s[i]<='9')//数字{if(b[2])return 0;dp[i&1][s[i]-'0'+53]=dp[(i-1)&1][63]-dp[(i-1)&1][s[i]-'0'+53];}else if(s[i]>='a'&&s[i]<='z')//小写{if(b[0]&&b[1])return 0;if(!b[1])dp[i&1][s[i]-'a'+27]=dp[(i-1)&1][63]-dp[(i-1)&1][s[i]-'a'+27];if(!b[0])dp[i&1][s[i]-'a'+1]=dp[(i-1)&1][63]-dp[(i-1)&1][s[i]-'a'+1];;}else //问号{  for(int j=1;j<=62;j++){if(b[0]&&j>=1&&j<=26)continue;if(b[1]&&j>=27&&j<=52)continue;if(b[2]&&j>=53)continue;dp[i&1][j]=dp[(i-1)&1][63]-dp[(i-1)&1][j];}}for(int j=1;j<=62;j++)(dp[i&1][63]+=dp[i&1][j]%mod)%=mod;}return dp[n&1][63];
}
void solve()
{cin>>n;cin>>s;s=" "+s;int sum=get();b[0]=1,b[1]=0,b[2]=0,sum-=get();b[0]=0,b[1]=1,b[2]=0,sum-=get();b[0]=0,b[1]=0,b[2]=1,sum-=get();b[0]=1,b[1]=1,b[2]=0,sum+=get();b[0]=1,b[1]=0,b[2]=1,sum+=get();b[0]=0,b[1]=1,b[2]=1,sum+=get();// b[0]=1,b[1]=1,b[2]=1,sum-=get();//都不存在的情况,实际上这部分一定为0cout<<(sum%mod+mod)%mod<<endl;
}
signed main()
{Mirai;int T=1;//cin>>T;while(T--){solve();}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/82075.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java 基础篇】Java标准输入流详解:读取用户输入的完整指南

Java是一门流行的编程语言&#xff0c;常用于开发各种类型的应用程序&#xff0c;包括控制台应用、桌面应用、Web应用等。在这些应用中&#xff0c;与用户进行交互是一项重要的任务。本文将重点介绍Java标准输入流&#xff0c;它是Java程序中用于从用户获取输入的关键组成部分。…

Vue3函数式编程

文章目录 前言一、三种编程风格1.template2.jsx/tsx3.函数式编写风格 二、函数式编程1.使用场景2.参数3.例子3.render渲染函数 总结 前言 本文主要记录vue3中的函数式编程以及其他编程风格的简介 一、三种编程风格 1.template Vue 使用一种基于 HTML 的模板语法&#xff0c;…

如何下载安装 WampServer 并结合 cpolar 内网穿透,轻松实现对本地服务的公网访问

文章目录 前言1.WampServer下载安装2.WampServer启动3.安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4.固定公网地址访问 前言 Wamp 是一个 Windows系统下的 Apache PHP Mysql 集成安装环境&#xff0c;是一组常用来…

R语言画图

简单记录一下 plot(lad_profile_relative$lad, lad_profile_relative$height, type"l", lwd1.5, xlabexpression(paste("LAD ", "(", m^2, m^-3, ")" )), ylab"Height (m)")X轴数据&#xff0c; Y轴数据 type, 标记类型 lw…

Vue基础之模板语法介绍

前言 上篇我分享了关于Vue的入门&#xff0c;简单的入了个门。本篇文章将要分享的内容为Vue的模板语法。 一、插值 1.1、文本 1.2、html 1.3、属性 1.4、class、style绑定 1.5、表达式 在Vue的模板语法中&#xff0c;插值是一种常用的方式来动态地将数据渲染到视图中。Vue使用双…

华为云ROMA Connect亮相Gartner®全球应用创新及商业解决方案峰会,助力企业应用集成和数字化转型

9月13日-9月14日 Gartner全球应用创新及商业解决方案峰会在伦敦举行 本届峰会以“重塑软件交付&#xff0c;驱动业务价值”为主题&#xff0c;全球1000多位业内专家交流最新的企业应用、软件工程、解决方案架构、集成与自动化、API等企业IT战略和新兴技术热门话题。 9月13日…

linux入门---共享内存

目录标题 共享内存的原理共享内存的理解shmget函数key和shmid的区别ipcs -m和shmctlshmatshmdt共享内存的通信共享内存的优点共享内存的缺点共享内存的特点 共享内存的原理 通过前面的内容我们知道不同的进程通过虚拟地址空间和页表能够将自己的数据映射到内存上的不同地方比如…

STM32的HAL库SPI操作(master 模式)-根据时序图配置SPI

SPI相关基础知识 SPI基本概念请自行百度&#xff0c;参考&#xff1a;百度百科SPI简介.我们讲重点和要注意的地方。 master模式下要关注的地方 接线一一对应 也就是说主控的MISO,MOSI,SCLK,[CSn]分别和设备的MISO,MOSI,SCLK,[CSn]一一对应相连&#xff0c;不交叉&#xff0…

OPC DCOM快速配置

目录 1 老系统配置 1.1 移除Windows 安全 1.2 建立相互能识别的用户账号 1.3 配置系统宽泛的DCOM设置 1.4 配置Server的特殊DCOM设置 1.5 恢复Windows安全 1 老系统配置 远程OPC访问必须在服务器和客户端两端配置DCOM。本文讲述如何正确配置 DCOM 的步骤并保证安全。 新…

个人博客网站一揽子:Docker搭建图床(Lsky Pro)

Lsky Pro 介绍 Lsky Pro 是一个用于在线上传、管理图片的图床程序&#xff0c;中文名&#xff1a;兰空图床&#xff0c;你可以将它作为自己的云上相册&#xff0c;亦可以当作你的写作贴图库。 兰空图床始于 2017 年 10 月&#xff0c;最早的版本由 ThinkPHP 5 开发&#xff0…

郑州大学图书馆许少辉《乡村振兴战略下传统村落文化旅游设计》中文文献——2023学生开学季辉少许

郑州大学图书馆许少辉《乡村振兴战略下传统村落文化旅游设计》中文文献——2023学生开学季辉少许

【PyTorch攻略(2/7)】 加载数据集

一、说明 PyTorch提供了两个数据原语&#xff1a;torch.utils.data.DataLoader和torch.utils.data.Dataset&#xff0c;允许您使用预加载的数据集以及您自己的数据。数据集存储样本及其相应的标签&#xff0c;DataLoader 围绕数据集包装一个可迭代对象&#xff0c;以便轻松访问…

Spring注解家族介绍: @RequestMapping

前言&#xff1a; 今天我们来介绍RequestMapping这个注解&#xff0c;这个注解的内容相对来讲比较少&#xff0c;篇幅会比较短。 目录 前言&#xff1a; RequestMapping 应用场景&#xff1a; 总结&#xff1a; RequestMapping RequestMapping 是一个用于映射 HTTP 请求…

【ELFK】之zookeeper

一、Zookeeper是什么&#xff1f; zooleeper是一个分布式服务管理框架。存储业务服务节点元数据及信息&#xff0c;并复制&#xff1b;通知客户端在zookeeper上注册的服务节点状态&#xff0c;通过文件系统通知机制 1、Zookeeper工作机制 Zookeeper从设计模式角度来理解 是…

Vue3 封装 element-plus 图标选择器

一、实现效果 二、实现步骤 2.1. 全局注册 icon 组件 // main.ts import App from ./App.vue; import { createApp } from vue; import * as ElementPlusIconsVue from element-plus/icons-vueconst app createApp(App);// 全局挂载和注册 element-plus 的所有 icon app.con…

Python Web开发:构建动态Web应用

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 Python已经成为一门流行…

FPGA纯verilog实现8路视频拼接显示,提供工程源码和技术支持

目录 1、前言版本更新说明免责声明 2、我已有的FPGA视频拼接叠加融合方案3、设计思路框架视频源选择OV5640摄像头配置及采集静态彩条视频拼接算法图像缓存视频输出 4、vivado工程详解5、工程移植说明vivado版本不一致处理FPGA型号不一致处理其他注意事项 6、上板调试验证并演示…

PHP8的类与对象的基本操作之成员方法-PHP8知识详解

成员方法是指在类中声明的函数。 在类中可以声明多个函数&#xff0c;所以对象中可以存在多个成员方法。类的成员方法可以通过关键字进行修饰&#xff0c;从而控制成员方法的商用权限。 函数和成员方法唯一的区别就是&#xff0c;函数实现的是某个独立的功能&#xff0c;而成…

Java8实战-总结30

Java8实战-总结30 并行数据处理与性能并行流正确使用并行流高效使用并行流 小结 并行数据处理与性能 并行流 正确使用并行流 错用并行流而产生错误的首要原因&#xff0c;就是使用的算法改变了某些共享状态。下面是另一种实现对前n个自然数求和的方法&#xff0c;但这会改变…

RocketMQ 发送顺序消息

文章目录 顺序消息应用场景消息组&#xff08;MessageGroup&#xff09;顺序性生产的顺序性MQ 存储的顺序性消费的顺序性 rocketmq-client-java 示例&#xff08;gRPC 协议&#xff09;1. 创建 FIFO 主题生产者代码消费者代码解决办法解决后执行结果 rocketmq-client 示例&…