1. 程式人生 > 其它 >[luogu p3654] First Step (ファーストステップ)

[luogu p3654] First Step (ファーストステップ)

技術標籤:ssl演算法列表cspcurl

傳送門

First Step (ファーストステップ)

題目背景

知らないことばかりなにもかもが(どうしたらいいの?)

一切的一切 盡是充滿了未知數(該如何是好)

それでも期待で足が軽いよ(ジャンプだ!)

但我仍因滿懷期待而步伐輕盈(起跳吧!)

溫度差なんていつか消しちゃえってね

冷若冰霜的態度 有朝一日將會消失得無影無蹤

元気だよ元気をだしていくよ

拿出活力 打起精神向前邁進吧

我們Aqours,要第一次舉辦演唱會啦!

雖然學生會長看上去不怎麼支援我們的樣子,可是有了理事長的支援,我們還是被允許在校內的籃球場裡歌唱! 歌曲也好好地準備過了,名字叫"

最喜歡的話就沒問題! (ダイスキだったらダイジョウブ!)",大家一定會喜歡的吧!

演唱會一定會順利進行的!

希望不要發生停電什麼的事故哦......!

題目描述

可是......這個籃球場,好像很久沒有使用過的樣子啊......

裡面堆滿了學校的各種雜物呢...... 我

們Aqours的成員要怎麼在裡面列隊站下呢?

我們浦之星女子學院的籃球場是一個R行C列的矩陣,其中堆滿了各種學校的雜物 (用"#"表示),空地 (用"."表示) 好像並不多的樣子呢......

我們Aqours現在已經一共有K個隊員了,要歌唱舞蹈起來的話,我們得排成一條1*K的直線,一個接一個地站在籃球場的空地上呢 (橫豎均可)。

我們想知道一共有多少種可行的站位方式呢。

Aqours的真正的粉絲的你,能幫我們算算嗎?

輸入輸出格式

輸入格式

第一行三個整數 R, C, K。 接下來的R行C列,是浦之星女子學院籃球場。

輸出格式

總共的站位方式數量。

輸入輸出樣例

輸入樣例 #1

5 5 2
.###.
##.#.
..#..
#..#.
#.###

輸出樣例 #1

8

說明

R        C          K         備註
1-2      <=10     <=10       <=min(R,C)  無
3-4      <=100    <=100      1           無        
5-6      <=100    <=100      <=min(R,C)  沒有障礙
7-10     <=100    <=100      <=min(R,C)  無

以下是彩蛋

在LoveLive!Sunshine!!動畫第一季第三集中,Aqours隊長高海千歌演唱“最喜歡的話就沒問題!”到副歌前時,學校因為雷擊停電。

分析

我只想說,這道題除了題意,我其他都沒咋看懂……什麼Aqours,LoveLive!Sunshine!!學校我對其一無所知……(

這道題顯然有\(\operatorname{O}(rck)\),也就是立方級別的做法,就是列舉每一個位置,然後再分別往右,往下的方向試探\(k\)個數,如果夠了那就ans++。

顯然這種做法非常浪費時間,不過也恰好能過本題100量級的資料qaq。

這道題其實完全可以有\(\operatorname{O}(rc)\)做法的。列舉每一條橫著的數列和縱向的數列,然後掃描每次連續的空位,判斷空位的長度\(len\)是否大於等於\(k\)。如果是的,此時ans += len - k + 1

注意橫向縱向都得掃哦!除非一種特殊情況:\(k = 1\)。此時只掃描一次橫向就可以了,結果就是倉庫中空位的數量,如果橫縱都算一遍會算重。

上程式碼。

程式碼

/*
 * @Author: crab-in-the-northeast 
 * @Date: 2020-04-02 21:52:34 
 * @Last Modified by: crab-in-the-northeast
 * @Last Modified time: 2020-04-02 22:57:59
 */
#include <iostream>
#include <cstdio>

const int maxr = 105;
const int maxc = 105;

char g[maxr][maxc];

int main() {
    int r, c, k, ans = 0;
    std :: cin >> r >> c >> k;
    for(int i = 1; i <= r; i++) 
        scanf("%s", g[i] + 1);
    for(int i = 1; i <= r; i++) {
        int len = 0;
        for(int j = 1; j <= c + 1; j++) {
            if(g[i][j] == '.') len++;
            else {
                if(k <= len) ans += len - k + 1;
                len = 0;
            }
        }
    }
    if(k == 1) {
        std :: cout << ans << std :: endl;
        return 0;        
    }
    for(int i = 1; i <= c; i++) {
        int len = 0;
        for(int j = 1;  j <= r + 1; j++) {
            if(g[j][i] == '.') len++;
            else {
                if(k <= len) ans += len - k + 1;
                len = 0;
            }
        }
    }
    std :: cout << ans << std :: endl;
    return 0;
}

評測結果