第六屆藍橋杯【省賽試題9】壘骰子 ( 矩陣快速冪 )
題目描述:
賭聖atm晚年迷戀上了壘骰子,就是把骰子一個壘在另一個上邊,不能歪歪扭扭,要壘成方柱體。
經過長期觀察,atm 發現了穩定骰子的奧祕:有些數字的面貼著會互相排斥! 我們先來規範一下骰子:1 的對面是 4,2 的對面是 5,3 的對面是 6。
假設有 m 組互斥現象,每組中的那兩個數字的面緊貼在一起,骰子就不能穩定的壘起來。 atm想計算一下有多少種不同的可能的壘骰子方式。
兩種壘骰子方式相同,當且僅當這兩種方式中對應高度的骰子的對應數字的朝向都相同。 由於方案數可能過多,請輸出模 10^9 + 7 的結果。
不要小看了 atm 的骰子數量哦~
「輸入格式」
第一行兩個整數 n m n表示骰子數目
接下來 m 行,每行兩個整數 a b ,表示 a 和 b 數字不能緊貼在一起。
「輸出格式」
一行一個數,表示答案模 10^9 + 7 的結果。
「樣例輸入」
2 1
1 2
「樣例輸出」 544
「資料範圍」
對於 30% 的資料:n <= 5 對於 60% 的資料:n <= 100
對於 100% 的資料:0 < n <= 10^9, m <= 36
資源約定:
峰值記憶體消耗 < 256M CPU消耗 < 2000ms
請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入...” 的多餘內容。
所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。
注意: main函式需要返回0
注意: 只使用ANSI C/ANSI C++ 標準,不要呼叫依賴於編譯環境或作業系統的特殊函式。 注意: 所有依賴的函式必須明確地在原始檔中 #include <xxx>, 不能通過工程設定而省略常用標頭檔案。
提交時,注意選擇所期望的編譯器型別。
題目思路:
簡單矩陣快速冪的應用,求出遞推矩陣,程式設計實現即可。
遞推式:設dp[ i ][ j ]表示第 i 個骰子 j 面朝上的擺法有幾種
遞推矩陣:(根據遞推式很容易可以寫出)
矩陣T中 元素 T[ i ][ j ] 表示 i 面和 j 面的衝突關係
矩陣A中 元素A[ 1 ][ j ]表示 第1個骰子,j 面朝上的擺法有多少種,A乘一次T算出的是2個骰子。
最後,當一個面朝上的時候,骰子可以旋轉,讓別的面朝向不同,得到不同的擺法,所以最後要在得出的結果乘以 4^n
題目程式碼:
#include<cstdio> #include<cstring> #include<cmath> #define MOD 1000000007 #define LL long long using namespace std; struct Matrix{ LL v[6][6]; Matrix(){memset(v,0,sizeof(v));} }; Matrix mul(Matrix x ,Matrix y){ Matrix ans; for(int i=0 ;i<6 ;i++){ for(int j=0 ;j<6 ;j++){ for(int k=0 ;k<6 ;k++){ ans.v[i][j] = (ans.v[i][j] + x.v[i][k]*y.v[k][j])%MOD; } } } return ans; } Matrix q_pow(Matrix x,int k){ Matrix ans; for(int i=0 ;i<6 ;i++) ans.v[i][i] = 1; while(k){ if(k&1) ans = mul(ans,x); x = mul(x,x); k >>= 1; } return ans; } int n,m,a,b;; int main(){ //初始化 Matrix T,ans; for(int i=0 ;i<6 ;i++){ for(int j=0 ;j<6 ;j++){ T.v[i][j] = 1; } } //資料輸入 scanf("%d%d",&n,&m); for(int i=0 ;i<m ;i++){ scanf("%d%d",&a,&b); T.v[a-1][b-1] = 0; T.v[b-1][a-1] = 0; } //資料處理 ans = q_pow(T,n-1); int sum = 0; for(int i=0 ;i<6 ;i++){ for(int j=0 ;j<6 ;j++){ sum = (sum+ans.v[i][j])%MOD; } } //結果輸出 printf("%d\n",(sum*((int)pow(4,n))%MOD)%MOD); return 0; }
相關推薦
第六屆藍橋杯【省賽試題9】壘骰子 ( 矩陣快速冪 )
題目描述: 賭聖atm晚年迷戀上了壘骰子,就是把骰子一個壘在另一個上邊,不能歪歪扭扭,要壘成方柱體。 經過長期觀察,atm 發現了穩定骰子的奧祕:有些數字的面貼著會互相排斥! 我們先來規範一下骰子:
第六屆藍橋杯【省賽試題3】三羊獻瑞
題目描述: 觀察下面的加法算式: 其中,相同的漢字代表相同的數字,不同的漢字代表不同的數字。 請你填寫“三羊獻瑞”所代表的4位數字(答案唯一),不要填寫任何多餘內容。 題目答案: 1085
第八屆藍橋杯【省賽試題5】取數位
題目描述: 求1個整數的第k位數字有很多種方法。 以下的方法就是一種。// 求x用10進製表示時的數位長度 int len(int x){ if(x<10) return 1; retur
第八屆藍橋杯【省賽試題2】等差素數列
題目描述: 2,3,5,7,11,13,....是素數序列。 類似:7,37,67,97,127,157 這樣完全由素陣列成的等差數列,叫等差素數數列。 上邊的數列公差為30,長度為6。 2004年,
2017第八屆藍橋杯Java省賽
第一題:購物單 小明剛剛找到工作,老闆人很好,只是老闆夫人很愛購物。老闆忙的時候經常讓小明幫忙到商場代為購物。小明很厭煩,但又不好推辭。 這不,XX大促銷又來了!老闆夫人開出了長長的購物單,都是有打折優惠的。 小明也有個怪癖,不到萬不得已,從不刷卡,直
2017第八屆藍橋杯Java省賽有感
相對於ACM程式設計大賽的難度,藍橋杯就算容易一些了,第八屆的難度比前兩屆也提高了不少,建議在HDOJ上多加練習,這樣就能輕鬆些。 從準備上講藍橋杯有很多題都有固定的套路,大量練習是必不可少的,校內選拔之後,就開始不斷的刷題總結的無限迴圈中。 臨
(第七屆藍橋杯個人賽省賽)結果填空、程式碼填空
一、煤球數目(暴力解法,容易) 有一堆煤球,堆成三角稜錐形。具體: 第一層放1個, 第二層3個(排列成三角形), 第三層6個(排列成三角形), 第四層10個(排列成三角形), .... 如果一共有100層,共有多少個煤球? 請填表示煤球總數目的數字。 注
第十屆藍橋杯C++省賽A組(A題平方和)
std image code 判斷 省賽 條件 alt com == 只需要按照題目暴力算就完事了,最後結果是2658417853,代碼如下: #include <bits/stdc++.h> typedef long long ll; bool
第六屆藍橋杯B組C++試題
4. 格子中輸出 StringInGrid函式會在一個指定大小的格子中列印指定的字串。 要求字串在水平、垂直兩個方向上都居中。 如果字串太長,就截斷。 如果不能恰好居中,可以稍稍偏左或者偏上一點。 下面的程式實現這個邏輯,請填寫劃線部分缺少的程式碼。 #include <stdio.h> #in
【暴力自動生成排列】(2015)第六屆藍橋杯省賽 C/C++ B組 題解(第三題)
第三題題目三羊獻瑞觀察下面的加法算式: 祥 瑞 生 輝 + 三 羊 獻 瑞------------------- 三 羊 生 瑞 氣(如果有對齊問題,可以參看【圖1.jpg】)其中
加法變乘法——第六屆藍橋杯C語言B組(省賽)第六題
clu 自己 nbsp 加法 藍橋杯 重新 () std spa 原創 加法變乘法 我們都知道:1+2+3+ ... + 49 = 1225現在要求你把其中兩個不相鄰的加號變成乘號,使得結果為2015 比如:1+2+3+...+10*11+12+...+27*28+29+
三羊獻瑞——第六屆藍橋杯C語言B組(省賽)第三題
lan font oid 漢字 print ack size IV cnblogs 原創 三羊獻瑞 觀察下面的加法算式: 祥 瑞 生 輝 + 三 羊 獻 瑞 ------------------- 三 羊 生 瑞 氣 (如果有對齊問題,可以參看【圖1.jp
第六屆藍橋杯 軟體類省賽真題 第七題:加法變乘法
加法變乘法 我們都知道:1+2+3+ ... + 49 = 1225 現在要求你把其中兩個不相鄰的加號變成乘號,使得結果為2015 比如: 1+2+3+...+10*11+12+...+27*28+29+...+49 = 2015 就是符合要求的答案。 請你尋找另外一個可能
2015年第六屆藍橋杯C/C++程式設計本科B組省賽-星系炸彈(結果填空)
#include <iostream> using namespace std; int isYear(int year) { if(year%4==0&&year%100!=0||year%400==0)) return 1; else
2015第六屆藍橋杯全國軟體大賽省賽(預賽)總結
這是我上大學以來第一次自發的寫總結,這也許意味著我對大學的看法和接下來的大學生活都將有所改變吧。首先說說引導我寫這篇總結的“人物”吧,RUI,從大一開始便是同學,直到大三成為了舍友。他的成績一直很好,如果沒記錯的話,大一專業第一名,大二好像也是第一第二的,總之在班裡一直名列
2015年第六屆藍橋杯本科B組C++省賽個人題解
比賽結束已經一星期了,成績也出來了,江蘇非211組的省前十,但是深感自己還是有太多的不足。絕對不能以自己還只是大一為藉口,acm這條路還長的很。 目測得了95分(滿分150),第一題錯了,程式碼填空第一題錯了,倒數第二題扣了一點分,最後一道大題全錯。 之所以會這麼
第六屆藍橋杯省賽試題--壘骰子 解題報告
PS: 關於本題演算法的優化演算法已經發表, 請檢視疊骰子( 以矩陣方法實現 ) 原題: 賭聖atm晚年迷戀上了壘骰子,就是把骰子一個壘在另一個上邊,不能歪歪扭扭,要壘成方柱體。 經過長期觀察,atm 發現了穩定骰子的奧祕:有些數字的面貼著會互相排斥! 我們先來規範一下骰子
第六屆藍橋杯省賽
一、三角形面積 如【圖1】所示。圖中的所有小方格面積都是1。 那麼,圖中的三角形面積應該是多少呢? 請填寫三角形的面積。不要填寫任何多餘內容或說明性文字。 分析:(該正方形的面積減去其他三
第六屆-藍橋杯省賽-生命之樹
10、生命之樹 在X森林裡,上帝建立了生命之樹。他給每棵樹的每個節點(葉子也稱為一個節點)上,都標了一個整數,代表這個點的和諧值。上帝要在這棵樹內選出一個非空節點集S,使得對於S中的任意兩個點a,b,都存在一個點列 {a, v1, v2, ..., vk, b} 使得這個點
藍橋測試1->2015年第六屆藍橋杯省賽
1.StringInGrid函式會在一個指定大小的格子中列印指定的字串。 要求字串在水平、垂直兩個方向上都居中。 如果字串太長,就截斷。 如果不能恰好居中,可以稍稍偏左或者偏上一點。 下面的程式實現這個邏輯,請填寫劃線部分缺少的程式碼。 #include <s