题解

遇见平方和就转有序对呗

dp类似从很多点出发每次走一步的转移方式

然后我too naive的,枚举路径长度来决定更新次数,愉快TLE

改成记搜就过了

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define MAXN 100005
#define mo 994711
//#define ivorysi
using namespace std;
typedef long long int64;
typedef long double db;
typedef unsigned int u32;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
const int MOD = 1000000009;
int N,M,dp[35][35][35][35],cur,cnt;
char s[35][35];
int dx[2][5],dy[2][5];
int X[3] = {0,1,1};
int Y[3] = {1,0,1};
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
void update(int &x,int y) {
x = inc(x,y);
}
inline bool check(int on,int x,int y,int d,int c) {
if(X[c] && (!dx[on][d])) return false;
if(Y[c] && (!dy[on][d])) return false;
int tx = x + X[c] * dx[on][d];
int ty = y + Y[c] * dy[on][d];
if(tx < 1 || tx > N) return false;
if(ty < 1 || ty > M) return false;
return true;
}
int DP(int x1,int y1,int x2,int y2,int l,int v) {
if(dp[x1][y1][x2][y2] != -1) return dp[x1][y1][x2][y2];
if(s[x1][y1] != s[x2][y2]) return 0;
dp[x1][y1][x2][y2] = 1;
for(int a = 0 ; a <= 2 ; ++a) {
for(int b = 0 ; b <= 2 ; ++b) {
if(check(0,x1,y1,l,a) && check(1,x2,y2,v,b)) {
int tx1 = x1 + X[a] * dx[0][l];
int ty1 = y1 + Y[a] * dy[0][l];
int tx2 = x2 + X[b] * dx[1][v];
int ty2 = y2 + Y[b] * dy[1][v];
update(dp[x1][y1][x2][y2],DP(tx1,ty1,tx2,ty2,l,v));
}
}
}
return dp[x1][y1][x2][y2];
}
int Calc(int Len) {
cur = 0;
int res = 0; for(int l = 0 ; l <= 3 ; ++l) {
for(int v = 0 ; v <= 3 ; ++v) {
memset(dp,-1,sizeof(dp));
for(int i = 1 ; i <= N ; ++i) {
for(int j = 1 ; j <= M ; ++j) {
for(int k = 1 ; k <= N ; ++k) {
for(int h = 1 ; h <= M ; ++h) {
if(s[i][j] != s[k][h]) continue;
update(res,inc(DP(i,j,k,h,l,v),MOD - 1)); }
}
}
}
}
}
return res;
}
void Solve() {
read(N);read(M);
int ans = 0;
for(int i = 1 ; i <= N ; ++i) scanf("%s",s[i] + 1);
dx[0][0] = dx[1][0] = 1;dx[0][1] = dx[1][1] = 1;dx[0][2] = dx[1][2] = -1;dx[0][3] = dx[1][3] = -1;
dy[0][0] = dy[1][0] = 1;dy[0][1] = dy[1][1] = -1;dy[0][2] = dy[1][2] = 1;dy[0][3] = dy[1][3] = -1;
update(ans,Calc(N + M));
dx[0][0] = 1;dx[0][1] = -1;dx[0][2] = 0;dx[0][3] = 0;
dy[0][0] = 0;dy[0][1] = 0;dy[0][2] = 1;dy[0][3] = -1;
update(ans,MOD - Calc(max(N,M)));
for(int i = 0 ; i <= 3 ; ++i) {
swap(dx[0][i],dx[1][i]);
swap(dy[0][i],dy[1][i]);
}
update(ans,MOD - Calc(max(N,M)));
memcpy(dx[0],dx[1],sizeof(dx[1]));
memcpy(dy[0],dy[1],sizeof(dy[1]));
update(ans,Calc(max(N,M)));
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

【LOJ】#2178. 「BJOI2017」机动训练的更多相关文章

  1. Loj #3042. 「ZJOI2019」麻将

    Loj #3042. 「ZJOI2019」麻将 题目描述 九条可怜是一个热爱打麻将的女孩子.因此她出了一道和麻将相关的题目,希望这题不会让你对麻将的热爱消失殆尽. 今天,可怜想要打麻将,但是她的朋友们 ...

  2. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  3. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  4. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  5. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

  6. Loj #2542. 「PKUWC2018」随机游走

    Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...

  7. Loj #3059. 「HNOI2019」序列

    Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...

  8. Loj #3056. 「HNOI2019」多边形

    Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...

  9. Loj #3055. 「HNOI2019」JOJO

    Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...

随机推荐

  1. 【刷题】BZOJ 3495 PA2010 Riddle

    Description 有n个城镇被分成了k个郡,有m条连接城镇的无向边. 要求给每个郡选择一个城镇作为首都,满足每条边至少有一个端点是首都. Input 第一行有三个整数,城镇数n(1<=n& ...

  2. Andrew Ng机器学习课程,第一周作业,python版本

    Liner Regression 1.梯度下降算法 Cost Function 对其求导: theta更新函数: 代码如下: from numpy import * import numpy as n ...

  3. CXF wsdl2java 生成java代码供客户端使用

    CXF wsdl2java 生成java代码供客户端使用 环境配置:1.下载apache-cxf-2.6.2在环境变量中配置CXF_HOME 值为E:\gavin\cxf\apache-cxf-3.0 ...

  4. c#:无法将 NULL 转换成“System.DateTime”,因为它是一种值类型

    摘自:http://www.blogjava.net/parable-myth/archive/2010/09/30/333454.html 在C# 2.0里面的数据类型中,分为值类型和引用类型,引用 ...

  5. bzoj千题计划240:bzoj3900: 交换茸角

    http://www.lydsy.com/JudgeOnline/problem.php?id=3900 dp[i]表示让状态为i的鹿满足要求的最少交换次数 不能枚举两头鹿交换,因为一头鹿可能交换多次 ...

  6. HDU 4315 阶梯博弈变形

    n个棋子,其中第k个是红色的,每个棋子只能往上爬,而且不能越过.重叠其他棋子,谁将红色棋子移到顶部谁赢. 由于只能往上爬,所以很像阶梯博弈.这题有2个限制,棋子不能重叠,有红棋存在 首先不考虑红色棋, ...

  7. JMS学习(二)之ActiveMQ

    1,ActiveMQ是Apache实现的基于JMS的一个消息服务器.下面记录ActiveMQ的一些基本知识. 2,ActiveMQ connectors:ActiveMQ providesconnec ...

  8. CS229 笔记02

    CS229 笔记02 公式推导 $ {\text {For simplicity, Let }} A, B, C \in {\Bbb {R}}^{n \times n}. $ ​ $ {\bf {\t ...

  9. JavaScript 中创建三种消息框:警告框、确认框、提示框。

    网址:http://www.w3school.com.cn/js/js_popup.asp 警告框 警告框经常用于确保用户可以得到某些信息. 当警告框出现后,用户需要点击确定按钮才能继续进行操作. 语 ...

  10. 图的最短路径-----------Dijkstra算法详解(TjuOj2870_The Kth City)

    做OJ需要用到搜索最短路径的题,于是整理了一下关于图的搜索算法: 图的搜索大致有三种比较常用的算法: 迪杰斯特拉算法(Dijkstra算法) 弗洛伊德算法(Floyd算法) SPFA算法 Dijkst ...