1. 程式人生 > >洛谷——P2049 魔術棋子

洛谷——P2049 魔術棋子

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_queue
<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; }
20分TLE的dfs 技術分享
#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 魔術棋子