魔术棋子

题目描述

在一个M×N的魔术棋盘中,每个格子中均有一个整数,当棋子走进这个格子中,则此棋子上的数会被乘以此格子中的数。一个棋子从左上角走到右下角,只能向右或向下行动,请问此棋子走到右下角后,模(mod)K可以为几?

如以下2×3棋盘:

3 4 4

5 6 6

棋子初始数为1,开始从左上角进入棋盘,走到右下角,上图中,最后棋子上的数可能为288,432或540。所以当K=5时,可求得最后的结果为:0,2,3。

输入输出格式

输入格式:

第一行为三个数,分别为M,N,K(1≤M,N,K≤100);

以下M行,每行N个数,分别为此方阵中的数。

输出格式:

第一行为可能的结果个数;

第二行为所有可能的结果(按升序输出)。

输入输出样例

输入样例:
2 3 5
3 4 4
5 6 6
输出样例:
3
0 2 3

思路:记忆化搜索,统计结果,避免重复搜索。
代码:
//程序名:新的C++程序
//作者: 

#include<iostream>
#include<fstream>
#include<algorithm>

using namespace std;
int a[105][105],anss,n,m,k;
bool ans[105],b[105][105][105];
void dfs(int x,int y,int z)
{
    if(x>n||y>m)return;
    z*=a[x][y];z%=k;
    if(b[x][y][z]==true)return;
    b[x][y][z]=true;
    if(x==n&&y==m)
    {
        if(ans[z]==false)anss++;
        ans[z]=true;
    }
    dfs(x+1,y,z);
    dfs(x,y+1,z);
}
void write()
{
    int f=1,t=0;
    cout<<anss<<endl;
    for(int i=0;i<k;i++)if(ans[i]){if(f)cout<<i,f=0;else cout<<" "<<i;}
}
int main()
{
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>a[i][j],a[i][j]%=k;
    dfs(1,1,1);
    write();
    return 0;
}
View Code

 

 
posted @ 2019-06-05 12:37  背‘水’一栈  阅读(370)  评论(0编辑  收藏  举报