P11788 [JOI 2019 Final] 勇者比太郎 / Bitaro the Brave
题目描述
勇者比太郎正在面对恶魔。
为了攻击恶魔,比太郎会在一个 H×WH\times WH×W 的网格上放置三种道具(分别记作 J,O,I)并施放咒语。网格上往下数第 iii 行 (1≤i≤H)(1\le i\le H)(1≤i≤H),左往右数第 jjj 列 (1≤j≤W)(1\le j\le W)(1≤j≤W) 的格子坐标记为 (i,j)(i,j)(i,j)。
现在,比太郎在网格的每个格子中放置了三种道具中的一种,比太郎将施放一个咒语,其威力取决于三种道具的排列方式。具体的,威力大小等于满足以下条件的有序四元组 (i,j,k,l)(i,j,k,l)(i,j,k,l),满足 (1≤i<k≤H,1≤j<l≤W)(1\le i<k\le H,1\le j<l\le W)(1≤i<k≤H,1≤j<l≤W) 的数量。
条件:(i,j)(i,j)(i,j) 位置的格子上的道具为 J,(i,l)(i,l)(i,l) 位置上的道具为 O,(k,j)(k,j)(k,j) 位置上的道具为 I。
比太郎想知道他的咒语的威力是多少。
请写一个程序,根据三种道具在网格上的排列,计算出咒语的威力(即满足上述条件的四元组数量)。
输入格式
第一行两个整数 H,WH,WH,W,表示网格长宽。
接下来 HHH 行,每行 WWW 个字符,描述网格每个格子的道具。
输出格式
一行一个整数,表示最大的威力。
输入输出样例 #1
输入 #1
3 4
JOIJ
JIOO
IIII
输出 #1
3
输入输出样例 #2
输入 #2
4 4
JJOO
JJOO
IIJO
IIIJ
输出 #2
17
说明/提示
【数据范围与约定】
- $ 2 \le H \le 3000 $。
- $ 2 \le W \le 3000 $。
- 对于 20%20 \%20% 的数据,$ H \le 100,W \le 100 $。
- 对于 30%30 \%30% 的数据,$ H \le 500,W \le 500 $。
- 对于 50%50 \%50% 的数据,无特殊限制。
C++实现
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=3005;
int H,W,sum_O[N][N],sum_I[N][N],ans;
char a[N][N];
signed main(){
scanf("%lld%lld",&H,&W);
for(int i=1;i<=H;i++)
for(int j=1;j<=W;j++)
cin>>a[i][j];
for(int i=1;i<=H;i++)
for(int j=W;j>=1;j--)
sum_O[i][j]=sum_O[i][j+1]+(a[i][j]=='O');
for(int j=1;j<=W;j++)
for(int i=H;i>=1;i--)
sum_I[i][j]=sum_I[i+1][j]+(a[i][j]=='I');
for(int i=1;i<=H;i++)
for(int j=1;j<=W;j++)
if(a[i][j]=='J')
ans+=sum_O[i][j]*sum_I[i][j];
printf("%lld",ans);
return 0;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

被折叠的 条评论
为什么被折叠?



