列表

详情


NC53187. 勇者比太郎

描述

译自 JOI 2019 Final T1「勇者ビ太郎 / Bitaro the Brave
勇者比太郎正在面对恶魔。
为了攻击恶魔,比太郎会在一个的网格上放置三种道具(分别记作J,O,I)并施放咒语。网格上往下数第i行(),左往右数第j列()的格子坐标记为(i,j)。
现在,比太郎在网格的每个格子中放置了三种道具中的一种,比太郎将施放一个咒语,其威力取决于三种道具的排列方式。具体的,威力大小等于满足以下条件的有序四元组的数量。
条件:(i,j)位置的格子上的道具为J,(i,l)位置上的道具为O,(k,j)位置上的道具为I。
比太郎想知道他的咒语的威力是多少。
请写一个程序,根据三种道具在网格上的排列,计算出咒语的威力(即满足上述条件的四元组数量)。

输入描述

从标准输入中读取数据。
第一行包括两个整数H,W,表示网格的高度和宽度。
接下来H行,第i行给出一个W位长的字符串S_i,表示网格第i行的道具。

输出描述

输出数据到标准输出中。
输出一行一个整数,表示比太郎的咒语的威力。

示例1

输入:

3 4
JOIJ
JIOO
IIII

输出:

3

说明:

在这个样例中,3个四元组分别是(1,1,3,2),(2,1,3,3),(2,1,3,4)。

示例2

输入:

4 4
JJOO
JJOO
IIJO
IIIJ

输出:

17

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 108ms, 内存消耗: 9296K, 提交时间: 2020-04-12 16:57:28

#include <bits/stdc++.h>
using namespace std;

const int maxn = 3e3 + 5;
int l[maxn];
char s[maxn][maxn];

int main() {

    int H, W;
    scanf("%d%d", &H, &W);
    for(int i = 1; i <= H; i++)
        scanf("%s", s[i]+1);

    long long ans = 0;
    for(int i = H; i; i--) {
        int tmp = 0;
        for(int j = W; j; j--)
            if(s[i][j] == 'O') tmp++;
            else if(s[i][j] == 'I') l[j]++;
            else ans += tmp * l[j];
    }
    printf("%lld", ans);
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 765ms, 内存消耗: 79964K, 提交时间: 2020-04-13 00:00:02

#include<iostream>
#define N 3010 
using namespace std;
int H,W;
char n[N][N];
int a[N][N],b[N][N];

int main()
{	
	cin>>H>>W;
	for(int i=1;i<=H;i++)
	cin>>n[i]+1;
	
	for(int i=1;i<=H;++i)
	for(int j=W;j>=1;--j)
	a[i][j]=a[i][j+1]+(n[i][j]=='O');

	for(int j=1;j<=W;++j)
	for(int i=H;i>=1;--i)
	b[i][j]=b[i+1][j]+(n[i][j]=='I');
	
	long long ans=0;
	for(int i=1;i<=H;++i)
	for(int j=1;j<=W;++j)
	if(n[i][j]=='J')
	ans+=1LL*a[i][j+1]*b[i+1][j];
	
	cout<<ans;
	return 0;
}

C(clang 3.9) 解法, 执行用时: 108ms, 内存消耗: 9576K, 提交时间: 2020-04-12 15:07:53

#include<stdio.h>
int main()
{
	int i,j,h,w,num=0;
	char a[3100][3100];
	long long ans=0;
	int b[3100]={0};
	scanf("%d %d",&h,&w);
	for(i=1;i<=h;++i)
		scanf("%s",a[i]+1);
	for(i=h;i>0;--i) 
	{
        for(j=1;j<=w;++j) 
		if(a[i][j]=='I')
			b[j]++;
        num=0;
        for(j=w;j>0;--j)
        {
			if(a[i][j]=='O')
                num++;
            if(a[i][j]=='J')
                ans+=b[j]*num;
    	}
    }
    printf("%lld",ans);
	return 0;
}

上一题