洛谷——P2049 魔術棋子
阿新 • • 發佈:2017-09-22
empty gif 行動 結果 char emp bool 初始 魔術
P2049 魔術棋子
題目描述
在一個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:Magic.in 2 3 5 3 4 4 5 6 6輸出樣例#1:
3 0 2 3
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; priority_queue20分TLE的dfs<int,vector<int>,greater<int> >q; int n,m,mod,ans,a[110][110]; bool vist[110][110],vis[110]; int xx[2]={0,1},yy[2]={1,0}; int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘; ch=getchar();} return x*f; } void dfs(int x,int y,int s) { if(x==n&&y==m) { if(vis[s]) return ; vis[s]=true,ans++; q.push(s);return ; } for(int i=0;i<2;i++) { int fx=x+xx[i],fy=y+yy[i]; if(fx>0&&fy>0&&fx<=n&&fy<=m&&!vist[fx][fy]) { vist[fx][fy]=true; dfs(fx,fy,(s*a[fx][fy])%mod); vist[fx][fy]=false; } } } int main() { n=read(),m=read(),mod=read(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=read(),a[i][j]%=mod; dfs(1,1,a[1][1]); printf("%d\n",ans); while(!q.empty()) { n=q.top(); q.pop(); printf("%d ",n); } return 0; }
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m,mod,ans,a[110][110]; int xx[2]={0,1},yy[2]={1,0}; bool vist[110][110][110],vis[110]; priority_queue<int,vector<int>,greater<int> >q; int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘; ch=getchar();} return x*f; } void dfs(int x,int y,int s) { if(x==n&&y==m) { if(vis[s]) return ; vis[s]=true,ans++; q.push(s);return ; } if(vist[x][y][s]) return ; vist[x][y][s]=true; for(int i=0;i<2;i++) { int fx=x+xx[i],fy=y+yy[i]; if(fx>0&&fy>0&&fx<=n&&fy<=m) dfs(fx,fy,(s*a[fx][fy])%mod); } // vist[x][y][s]=false; } int main() { n=read(),m=read(),mod=read(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=read(),a[i][j]%=mod; dfs(1,1,a[1][1]); printf("%d\n",ans); while(!q.empty()) { n=q.top(); q.pop(); printf("%d ",n); } return 0; }AC的記憶化搜索
#include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; bool dp[110][110][110]; int n,m,k,ans,a[110][110]; int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1; ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘; ch=getchar();} return x*f; } int main() { n=read(),m=read(),k=read(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=read(),a[i][j]%=k; dp[1][1][a[1][1]]=true; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int s=0;s<k;s++) if(!dp[i][j][s*a[i][j]%k]) dp[i][j][s*a[i][j]%k]=dp[i][j-1][s]||dp[i-1][j][s]; for(int i=0;i<k;i++) if(dp[n][m][i]) ans++; printf("%d\n",ans); for(int i=0;i<k;i++) if(dp[n][m][i]) printf("%d ",i); return 0; }dp
洛谷——P2049 魔術棋子