初三奥赛模拟测试1--T1回文
初三奥赛模拟测试1--\(T1\)回文
题意
给定一个 \(n \times m\) 的,由字符组成的矩阵 \(A\) , 问你由 \(( 1 , 1 )\) 开始,点 \(( i , j )\) 只可以往 \(( i + 1 , j )\) 和 \(( i , j + 1 )\) 走,走到 \(( n , m )\) 停。
记录路径,问由路径上的字符构成的字符串能是回文串的走的种数 \(\bmod \ mod\) 的值 。
\(n \le 500\) , \(m \le 500\)
题解
一眼能看出来是 \(DP\) 哈,就是不知道怎么 \(DP\)
考虑一下回文串有什么性质。
首先设其长度为 \(len\) , 回文串为 \(s\) , 易看出一条性质 \(0\) :
\]
对于这个题,我们还有另外的性质:
1.无论怎么走,字符串长度是固定的。
2.设走到点 \(( i , j )\) 时,字符串达到的长度为 \(num_{ i , j }\) , 则无论如何跑, \(num_{ i , j }\) 不变。
3.对于第 \(i\) 行的第 \(j\) 个点, 他在字符串上与其距离为 \(l\) 点在第 \(k\) 行中最多匹配一个。
那么能看出其单调性了,也就是说存在构造方式使得更新过的点不再被更新。
如果不考虑第三个性质时我们的构造为:
\(dp_{ i , j , k , l }\) 表示点 \(( i , j )\) 和点 \(( k , l )\) 。
但我们有了性质\(3\) , 则可以构造为:
\(dp_{ i , j , k }\) 表示点 \(( i , j )\) 符合性质0 的另一个在第 \(k\) 行的点。
则 \(DP\) 转移方程如下:
inline void pd( int xi , int yi , int xj , int yj , int len )
{
flag = 0 ;
if ( num[ xi ][ yi + 1 ] + num[ xj ][ yj - 1 ] == len && yi + 1 <= m && yj - 1 > 0 )
{
flag = 1 ;
dp[ xi ][ yi ][ xj ] = ( dp[ xi ][ yi ][ xj ] + dp[ xi ][ yi + 1 ][ xj ] ) % mod ;
}
if ( num[ xi ][ yi + 1 ] + num[ xj - 1 ][ yj ] == len && yi + 1 <= m && xj - 1 > 0 )
{
flag = 1 ;
dp[ xi ][ yi ][ xj ] = ( dp[ xi ][ yi + 1 ][ xj - 1 ] + dp[ xi ][ yi ][ xj ] ) % mod ;
}
if ( num[ xi + 1 ][ yi ] + num[ xj ][ yj - 1 ] == len && xi + 1 <= n && yj - 1 > 0 )
{
flag = 1 ;
dp[ xi ][ yi ][ xj ] = ( dp[ xi + 1 ][ yi ][ xj ] + dp[ xi ][ yi ][ xj ] ) % mod ;
}
if ( num[ xi + 1 ][ yi ] + num[ xj - 1 ][ yj ] == len && xi + 1 <= n && xj - 1 > 0 )
{
flag = 1 ;
dp[ xi ][ yi ][ xj ] = ( dp[ xi + 1 ][ yi ][ xj - 1 ] + dp[ xi ][ yi ][ xj ] ) % mod ;
}
}
\(( x_i , y_i )\) 和 \((x_j , y_j )\) 为一对满足性质 \(0\) 且点权相等的点。
\(len = n+m\)
\(code\)
点我点我
#include <bits/stdc++.h>
using namespace std ;
const int mod = 993244853 ;
const int N = 510 ;
int n , m ;
char a[ N ][ N ] ;
struct node
{
int x , y ;
}pos[ N * 3 ][ N * 3 ] ;
int num[ N ][ N ] , nump[ N * 3 ] ;
unsigned int dp[ N ][ N ][ N ] ;
bool flag = 0 ;
inline int abss( int p )
{
if ( p < 0 ) return - p ;
return p ;
}
inline void pd( int xi , int yi , int xj , int yj , int len )
{
flag = 0 ;
if ( num[ xi ][ yi + 1 ] + num[ xj ][ yj - 1 ] == len && yi + 1 <= m && yj - 1 > 0 )
{
flag = 1 ;
dp[ xi ][ yi ][ xj ] = ( dp[ xi ][ yi ][ xj ] + dp[ xi ][ yi + 1 ][ xj ] ) % mod ;
}
if ( num[ xi ][ yi + 1 ] + num[ xj - 1 ][ yj ] == len && yi + 1 <= m && xj - 1 > 0 )
{
flag = 1 ;
dp[ xi ][ yi ][ xj ] = ( dp[ xi ][ yi + 1 ][ xj - 1 ] + dp[ xi ][ yi ][ xj ] ) % mod ;
}
if ( num[ xi + 1 ][ yi ] + num[ xj ][ yj - 1 ] == len && xi + 1 <= n && yj - 1 > 0 )
{
flag = 1 ;
dp[ xi ][ yi ][ xj ] = ( dp[ xi + 1 ][ yi ][ xj ] + dp[ xi ][ yi ][ xj ] ) % mod ;
}
if ( num[ xi + 1 ][ yi ] + num[ xj - 1 ][ yj ] == len && xi + 1 <= n && xj - 1 > 0 )
{
flag = 1 ;
dp[ xi ][ yi ][ xj ] = ( dp[ xi + 1 ][ yi ][ xj - 1 ] + dp[ xi ][ yi ][ xj ] ) % mod ;
}
if ( flag == 1 && dp[ xi ][ yi ][ xj ] == 0 && ( n + m - 1 ) % 2 == 0 )
{
if ( ( xi == xj && ( abss( yi - yj ) == 1 ) || ( yi == yj && ( abss( xi - xj ) == 1 ) ) ) )
dp[ xi ][ yi ][ xj ] = 1 ;
}
dp[ xj ][ yj ][ xi ] = dp[ xi ][ yi ][ xj ] ;
}
signed main( )
{
ios::sync_with_stdio( 0 ) ; cin.tie( 0 ) ; cout.tie( 0 ) ;
cin >> n >> m ;
for (int i = 1 ; i <= n ; ++ i )
{
for ( int j = 1 ; j <= m ; ++ j )
{
cin >> a[ i ][ j ] ;
if ( num[ i - 1 ][ j ] )
{
num[ i ][ j ] = num[ i - 1 ][ j ] + 1 ;
}
else
{
if ( num[ i ][ j - 1 ] )
{
num[ i ][ j ] = num[ i ][ j - 1 ] + 1 ;
}
else num[ i ][ j ] = 1 ;
}
// cout << i << ' ' << j << ' ' << num[ i ][ j ] << '\n' ;
pos[ num[ i ][ j ] ][ ++ nump[ num[ i ][ j ] ] ] = { i , j } ;
}
}
// for ( int i = 1 ; i <= n ; ++ i )
// {
// for ( int j = 1 ; j <= m ; ++ j )
// {
// cout << setw( 5 ) << num[ i ][ j ] << ' ' ;
// }
// cout << '\n' ;
// }
if ( a[ 1 ][ 1 ] != a[ n ][ m ] )
{
cout << 0 ;
return 0 ;
}
int xi , yi , xj , yj ;
int len = n - 1 + m , mid = ( n + m ) >> 1 , lenk = n + m ;
for ( int i = mid ; i < lenk ; ++ i )
{
if ( i == mid && ( n - 1 + m ) % 2 == 1 )
{
for ( int j = 1 ; j <= nump[ i ] ; ++ j )
{
dp[ pos[ i ][ j ].x ][ pos[ i ][ j ].y ][ pos[ i ][ j ].x ] = 1 ;
}
continue ;
}
for ( int j = 1 ; j <= nump[ i ] ; ++ j )
{
xi = pos[ i ][ j ].x , yi = pos[ i ][ j ].y ;
for ( int k = 1 ; k <= nump[ lenk - i ] ; ++ k )
{
xj = pos[ lenk - i ][ k ].x , yj = pos[ lenk - i ][ k ].y ;
if ( a[ xi ][ yi ] == a[ xj ][ yj ] && xi >= xj && yi >= yj && xi > 0 && xj > 0 && yi > 0 && yj > 0 )
{
pd( xj , yj , xi , yi , lenk ) ;
}
}
}
}
cout << dp[ n ][ m ][ 1 ] << '\n' ;
}
结尾撒花 \(\color{pink}✿✿ヽ(°▽°)ノ✿\)
初三奥赛模拟测试1--T1回文的更多相关文章
- 【佛山市选2013】JZOJ2020年8月7日提高组T1 回文子序列
[佛山市选2013]JZOJ2020年8月7日提高组T1 回文子序列 题目 描述 回文序列是指左右对称的序列.例如1 2 3 2 1是回文序列,但是1 2 3 2 2就不是.我们会给定一个N×M的矩阵 ...
- 4.22 省选模拟赛 三元组 manacher 回文自动机
容易发现可以枚举j 那么只需要计算出 l~j这段是回文串的l的和 以及j+1~r这段是回文串的r的和. 可以manacher 之后想要求出以j为右端点的回文串左端点的和 这个东西我们通过某个点为中心的 ...
- [CSP-S模拟测试]:ants(回滚莫队)
题目描述 然而贪玩的$dirty$又开始了他的第三个游戏. $dirty$抓来了$n$只蚂蚁,并且赋予每只蚂蚁不同的编号,编号从$1$到$n$.最开始,它们按某个顺序排成一列.现在$dirty$想要进 ...
- 【20180807模拟测试】t1 function
low逼的我也只能写这样的水题... 题面 对于一个整数,定义 f(x)为他的每个数位的阶乘的乘积.例如 f(135)=1! * 3! * 5! =720.给出一个数 a(可以包含前缀零),a 满足他 ...
- 「题解」NOIP模拟测试题解乱写II(36)
毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...
- [python]回答百度知道上的问题2000-2999之间的回文日
因为百度知道的编辑器没有提供代码功能,将回复写入. 题目如下: 求2000到2999的所有回文日,例如20200202 用Python怎么做 回文年好求,回文日的话,年月日这咋存啊 思路一:遍历每一天 ...
- 10.1 csp-s模拟测试(b) X国的军队+排列组合+回文
T1 X国的军队 贪心,按$b-a$的大小降序排序,然后就贪心吧 #include<iostream> #include<cstdio> #include<algorit ...
- [CSP-S模拟测试]:回文(hash+二维前缀和)
题目描述 闲着无聊的$YGH$秒掉上面两道题之后,开始思考有趣的回文串问题了. 他面前就有一个漂浮着的字符串.显然$YGH$是会$manacher$的,于是他随手求出了这个字符串的回文子串个数.但是他 ...
- [CSP-S模拟测试]:回文串(hash+二分)
题目描述 $ASDFZ$的机房中不仅有红太阳,还有蓝太阳和原谅色太阳.有一天,太阳们来到机房,发现桌上有不知道哪个蒟蒻放上的问题:令$F(A,B)$表示选择一个串$A$的非空前缀$S$和串$B$的非空 ...
- csp-s模拟测试10.1(b)X 国的军队,排列组合, 回文题解
题面:https://www.cnblogs.com/Juve/articles/11615883.html X 国的军队: 好像有O(T*N)的直接贪心做法 其实多带一个log的二分也可以过 先对所 ...
随机推荐
- 算法金 | 致敬深度学习三巨头:不愧是腾讯,LeNet问的巨细。。。
大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 抱个拳,送个礼 读者参加面试,竟然在 LeNet 这个基础算法上被吊打~ LeNe ...
- Python潮流周刊的优惠券和精美电子书(EPUB、PDF、Markdown)
Python潮流周刊从 2023.05.13 连载至今,本周即将发布第 60 期,这意味着我们又要达成一个小小的里程碑啦! 每周坚持做分享,周复一周,这对自己的精力和意志是一项不小的挑战.于是,为了让 ...
- Asp .Net Core 系列:基于 T4 模板生成代码
目录 简介 组成部分 分类 Visual Studio 中使用T4模板 创建T4模板文件 2. 编写T4模板 3. 转换模板 中心控制Manager 根据 MySQL 数据生成 实体 简介 T4模板, ...
- oeasy教您玩转vim - 54 - # 匹配替换
查找细节 回忆上节课内容 我们学习了 替换 substitude 替换单行 :s/shiyanlou/oeasy 加上range :3,5s/shiyanlou/oeasy :%s/shiyanl ...
- Masked Popcount 题解
背景 罚了一发,太菜了.为什么我终于有时间的时候她要考试? 题意 给你 \(n,m\),问 \(\sum_{i=0}^{n}popcount(i \&m)\). 其中 \(\&\) 代 ...
- OLOR:已开源,向预训练权值对齐的强正则化方法 | AAAI 2024
随着预训练视觉模型的兴起,目前流行的视觉微调方法是完全微调.由于微调只专注于拟合下游训练集,因此存在知识遗忘的问题.论文提出了基于权值回滚的微调方法OLOR(One step Learning, On ...
- 由delete语句引起的锁范围扩大
由delete语句引起的锁范围扩大 阿里云月报中的一句话,出处:http://mysql.taobao.org/monthly/2022/01/01/ 但是Ghost Record是可以跟正常的Rec ...
- Python threading实现多线程 提高篇 线程同步,以及各种锁
本文主要讲多线程的线程之间的资源共享怎么保持同步. 多线程基础篇见,Python threading实现多线程 基础篇 Python的多线程,只有用于I/O密集型程序时效率才会有明显的提高,如文件/输 ...
- 写写Redis十大类型GEO(地理空间)的常用命令
又是一个用于处理sql性能的类型,这个类型的核心思想就是把三维的地球变成二维的坐标,再将二维的坐标换成一维的点块,最后将一维的点块转化成base32编码 类型就是zset, 在shell的启动命令后加 ...
- Linux podman容器实验
要求 1.登录到指定的镜像仓库拉取镜像 2.以普通用户contsvc运行 3.配置 systemd-journald 服务,要求永久保留日志数据(物理机,创建文件mkdir /var/log/jour ...