最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++實現(xiàn)藍橋杯競賽題目---搭積木

 更新時間:2021年07月06日 15:09:15   作者:一只特立獨行的貓  
這篇文章主要介紹了C++實現(xiàn)藍橋杯競賽題目---搭積木,本篇文章通過題目分析列舉公式進行分析算法,包含詳細的圖文,以下就是詳細內容,需要的朋友可以參考下

小明對搭積木非常感興趣。他的積木都是同樣大小的正立方體。
在搭積木時,小明選取 m 塊積木作為地基,將他們在桌子上一字排開,中間不留空隙,并稱其為第0層。
隨后,小明可以在上面擺放第1層,第2層,……,最多擺放至第n層。擺放積木必須遵循三條規(guī)則

規(guī)則1:每塊積木必須緊挨著放置在某一塊積木的正上方,與其下一層的積木對齊;

規(guī)則2:同一層中的積木必須連續(xù)擺放,中間不能留有空隙;

規(guī)則3:小明不喜歡的位置不能放置積木。

其中,小明不喜歡的位置都被標在了圖紙上。圖紙共有n行,從下至上的每一行分別對應積木的第1層至第n層。每一行都有m個字符,字符可能是‘.'或‘X',其中‘X'表示這個位置是小明不喜歡的。
現(xiàn)在,小明想要知道,共有多少種放置積木的方案。他找到了參加藍橋杯的你來幫他計算這個答案。
由于這個答案可能很大,你只需要回答這個答案對1000000007(十億零七)取模后的結果。
注意:地基上什么都不放,也算作是方案之一種。

輸入格式:
數(shù)據(jù)的第一行有兩個正整數(shù)n和m,表示圖紙的大小。
隨后n行,每行有m個字符,用來描述圖紙 。每個字符只可能是‘.'或‘X'。

輸出格式:
一個整數(shù),表示答案對1000000007取模后的結果。

輸入樣例1:

2 3

..X

.X.

輸出樣例1:

4

輸入樣例2:

3 3

..X

.X.

...

輸出樣例2:

16

解題思路:

在這里插入圖片描述

首先先推導出遞推式,觀察題目,可以得到遞推式為:

在這里插入圖片描述

用代碼表示即為:

for(int c=1;c<a;c++){
	for(int d=b;d<m;d++){
		dp[i][a][b]+=dp[i-1][c][d];
	}
}

意思是
在第i層的a到b長度放置積木的可能數(shù)=在i-1層的所有包含a到b的長度的積木的可能數(shù)的和。

除了單純的判斷遞推式以外,還需要考慮一種特殊情況,就是積木放置的長度中存在X,即小明不想放的位置,那么就不需要進行遞推,直接返回0。
判斷[a,b]是否存在X,可以用前綴和來判斷,節(jié)省時間。
前綴和初始化為:

s[i][j] = s[i][j-1] + (temp=='X');

推導出遞推式以后可以很容易的寫出代碼:

#include<iostream>

using namespace std;

const int N = 30;
int n, m;
int dp[30][30][30];
int s[30][30];
int cnt=1;

int main() {
	cin >> n >> m;
	getchar();
	for (int i = n; i >0; i--) {//初始化前綴和
		for (int j = 1; j <= m; j++) {
			char temp = getchar();
			s[i][j] = s[i][j-1] + (temp=='X');
		}
		getchar();
	}
	dp[0][1][m]=1;//第0層,長度從1到m的積木有一種可能
	for (int i = 1; i <=n; i++) {//第i層
		for (int a = 1; a <= m; a++) {
			for (int b = a; b <= m; b++) {
				if (s[i][b] - s[i][a - 1] != 0) {//a到b區(qū)間存在X
					dp[i][a][b] = 0;
					continue;
				}
				for (int c = 1; c <= a; c++) {
					for (int d = b; d <= m; d++) {
						dp[i][a][b] += dp[i - 1][c][d];
					}
				}
				cnt += dp[i][a][b];//記錄數(shù)量
			}
		}
	}
	cout << cnt;
	return 0;
}

優(yōu)化

但是仔細一想,五個for循環(huán)無法通過最后50%的測試點,所以需要進行優(yōu)化,觀察最內層的兩個c,d的for循環(huán)可知,有如下圖像:

在這里插入圖片描述

實際上最內層的兩個循環(huán)就是在求第i-1層的紅色區(qū)域面積。
那我們再利用二維的前綴和進行存儲,那就可以優(yōu)化掉兩個循環(huán),從而使時間復雜度降低,通過最后的測試點。

#include<iostream>

using namespace std;

const int N = 30;
const int mod = 1e9 + 7;
int n, m;
int dp[30][30][30];
int s[30][30];//用來判斷是否存在X
int sum[30][30];//指的是左下角所有dp[i][][]的和
int cnt=1;

void get_fixsum(int i) {
	//更新第i層的前綴和數(shù)組
	for (int a = 1; a <= m; a++) {
		for (int b = 1; b <= m; b++) {
			sum[a][b] =(sum[a][b-1]+sum[a-1][b]-sum[a-1][b-1]+ dp[i][a][b])%mod;
		}
	}
}

int main() {
	cin >> n >> m;
	getchar();
	for (int i = n; i >0; i--) {
		for (int j = 1; j <= m; j++) {
			char temp = getchar();
			s[i][j] = s[i][j-1] + (temp=='X');
		}
		getchar();
	}
	dp[0][1][m]=1;//第0層,長度從1到m的積木有一種可能
	get_fixsum(0);
	for (int i = 1; i <=n; i++) {//層數(shù)
		for (int a = 1; a <= m; a++) {
			for (int b = a; b <= m; b++) {
				if (s[i][b] - s[i][a - 1] != 0) {//a到b區(qū)間存在X
					dp[i][a][b] = 0;
					continue;
				}
				dp[i][a][b] = (sum[a][m] - sum[0][m] - sum[a][b-1] + sum[0][b-1])%mod;
				cnt =(cnt+ dp[i][a][b])%mod;
			}
		}
		get_fixsum(i);
	}
	cout << (cnt+mod)%mod;//防止出現(xiàn)負數(shù)
	return 0;
}

到此這篇關于C++實現(xiàn)藍橋杯競賽題目---搭積木的文章就介紹到這了,更多相關C++實現(xiàn)藍橋杯---搭積木內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C++中的Reactor原理與實現(xiàn)

    C++中的Reactor原理與實現(xiàn)

    reactor設計模式是event-driven?architecture的一種實現(xiàn)方式,處理多個客戶端并發(fā)的向服務端請求服務的場景,每種服務在服務端可能由多個方法組成,這篇文章主要介紹了Reactor原理與實現(xiàn),需要的朋友可以參考下
    2022-07-07
  • C語言報錯:Format String Vulnerability的多種解決方案

    C語言報錯:Format String Vulnerability的多種解決方案

    Format String Vulnerability(格式化字符串漏洞)是C語言中常見且嚴重的安全漏洞之一,它通常在程序使用不受信任的輸入作為格式化字符串時發(fā)生,本文將詳細介紹Format String Vulnerability的產生原因,提供多種解決方案,需要的朋友可以參考下
    2024-06-06
  • C/C++語言中結構體的內存分配小例子

    C/C++語言中結構體的內存分配小例子

    當未用 #pragma 指令指定編譯器的對齊位數(shù)時,結構體按最長寬度的數(shù)據(jù)成員的寬度對齊;當使用了 #pragma 指令指定編譯器的對齊位數(shù)時,結構體按最長寬度的數(shù)據(jù)成員的寬度和 #pragma 指令指定的位數(shù)中的較小值對齊
    2013-10-10
  • c++中創(chuàng)建.in文件的方法步驟

    c++中創(chuàng)建.in文件的方法步驟

    在本篇文章里小編給大家分享了一篇關于c++中創(chuàng)建.in文件的方法步驟的內容以及相關知識點,需要的朋友們學習下。
    2019-07-07
  • C語言求連續(xù)最大子數(shù)組和的方法

    C語言求連續(xù)最大子數(shù)組和的方法

    這篇文章主要介紹了C語言求連續(xù)最大子數(shù)組和的方法,包含了數(shù)組的常見操作及相關技巧,需要的朋友可以參考下
    2014-09-09
  • 如何使用C語言將數(shù)字、字符等數(shù)據(jù)寫入、輸出到文本文件中

    如何使用C語言將數(shù)字、字符等數(shù)據(jù)寫入、輸出到文本文件中

    在分析數(shù)據(jù)時,首先要解決數(shù)據(jù)的保存問題,下面這篇文章主要給大家介紹了關于如何使用C語言將數(shù)字、字符等數(shù)據(jù)寫入、輸出到文本文件中的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-06-06
  • fcntl函數(shù)的使用詳解

    fcntl函數(shù)的使用詳解

    本篇文章是對fcntl函數(shù)的使用進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • 一篇文章帶你入門C語言數(shù)據(jù)結構:緒論

    一篇文章帶你入門C語言數(shù)據(jù)結構:緒論

    這篇文章主要介紹了C語言的數(shù)據(jù)解構基礎,希望對廣大的程序愛好者有所幫助,同時祝大家有一個好成績,需要的朋友可以參考下,希望能給你帶來幫助
    2021-08-08
  • C++中static和const的作用和用法

    C++中static和const的作用和用法

    在C++中,"static"和"const"都是用于修飾變量的關鍵字,它們具有不同的作用,本文通過代碼示例給大家詳細的介紹static和const的作用和用法,,需要的朋友可以參考下
    2023-06-06
  • 用c++實現(xiàn)將文本每個單詞首字母轉換為大寫

    用c++實現(xiàn)將文本每個單詞首字母轉換為大寫

    本篇文章是對用c++實現(xiàn)將文本每個單詞首字母轉換為大寫的方法進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05

最新評論

如皋市| 栾城县| 色达县| 潜山县| 玉田县| 丹阳市| 长沙县| 屏山县| 奉贤区| 灌阳县| 宣恩县| 寿宁县| 雷州市| 鲁山县| 宿松县| 巩留县| 翁源县| 砚山县| 保德县| 鄂伦春自治旗| 龙山县| 乐都县| 寻甸| 易门县| 洞头县| 金昌市| 习水县| 秦皇岛市| 屏东县| 临西县| 灵宝市| 左贡县| 朝阳县| 航空| 沛县| 海城市| 仙桃市| 黄浦区| 齐齐哈尔市| 剑阁县| 恩平市|