在乙個m*n的魔術棋盤中,每個格仔中均有乙個整數,當棋子走進這個格仔中,則此棋子上的數會被乘以此格仔中的數。乙個棋子從左上角走到右下角,只能向右或向下行動,請問此棋子走到右下角後,模(mod)k可以為幾?
如以下2*3棋盤:
3 4 4
5 6 6
棋子初始數為1,開始從左上角進入棋盤,走到右下角,上圖中,最後棋子上的數可能為288,432或540。所以當k = 5時,可求得最後的結果為:0,2,3。
輸入格式:
輸入檔案magic.in第一行為三個數,分別為m,n,k (1 ≤ m,n,k ≤ 100)以下m行,每行n個數,分別為此方陣中的數。
輸出格式:
輸出檔案magic.out第一行為可能的結果個數
第二行為所有可能的結果(按公升序輸出)
輸入樣例#1: 複製
2 3 53 4 4
5 6 6
輸出樣例#1: 複製
30 2 3
/*dp[i][j][l]表示在位置(i,j)能不能得到l。
*/#include
#include
#include
#include
#include
using
namespace
std;
intm,n,k,ans;
int num[105][105
];bool dp[105][105][105
];inline
int read(int &num)
}int
main()
}dp[
1][1][num[1][1]]=true; //
初始化位置(1,1)的數
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
for(int l=0;l//
因為mod k 後得到的數一定小於k,所以從0到k列舉
if(!dp[i][j][l*num[i][j]%k]) //
沒有計算過
dp[i][j][l*num[i][j]%k]=dp[i-1][j][l]||dp[i][j-1][l]; //
l*num[i][j]%k表示當前格仔數乘從左邊或上邊傳下來的數l再mod k,dp[i-1][j][l]和dp[i][j-1][l]表示在上方或左方能不能得到l
for(int i=0;i//
找個數
printf(
"%d\n
",ans);
for(int i=0;i//
找可能得到的數
return0;
}
P2049 魔術棋子 題解
csdn同步 原題鏈結 簡要題意 在乙個 n times m 的魔術棋盤中,每個格仔中均有乙個整數,當棋子走進這個格仔中,則此棋子上的數會被乘以此格仔中的數。乙個棋子從左上角走到右下角,只能向右或向下行動,請問此棋子走到右下角後,模 k 可以為幾?原題題意足夠簡要了吧 n,m,k leq 100 考...
洛谷 P2049 魔術棋子
乙個比較簡單dp問題。我們先來分析一下題目,要找到所有的模的總數,首先可以想到,用dp i j 表示在 i,j 這個點所有的方案數。但是,這樣顯然不行。因為僅僅知道方案總數對求解下乙個狀態毫無幫助。那麼,我們就要記錄每乙個點所有可能的模。所以,我們用三維dp i j l 表示在 i,j 點是否能夠得...
洛谷 P2049 魔術棋子
在乙個m n的魔術棋盤中,每個格仔中均有乙個整數,當棋子走進這個格仔中,則此棋子上的數會被乘以此格仔中的數。乙個棋子從左上角走到右下角,只能向右或向下行動,請問此棋子走到右下角後,模 mod k可以為幾?如以下2 3棋盤 3 4 4 5 6 6 棋子初始數為1,開始從左上角進入棋盤,走到右下角,上圖...