题目描述
在一个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个数,分别为此方阵中的数。
输出格式
第一行为可能的结果个数
第二行为所有可能的结果(按升序输出)
输入输出样例
输入 #1
2 3 5
3 4 4
5 6 6
输出 #1
3
0 2 3
好久没写博客了,今天写几篇题解
最近在刷搜索的题目,发现搜索和DP可谓是相辅相成(大概就是那个意思),搜索可以解的题DP基本都可以解,而DP可以解的题搜索不一定可以解,本题既可以用搜索也可以用DP。
题目描述的挺清楚(又是取余),在进行输入的时候就可以对每个数进行取余运算(%k),可以减小数值。
先来说思路,其实也没啥思路,就是深搜,就硬搜,给我搜!但是硬搜过不了,因为会超时,所以要用到记忆化。
然后是数据结构:
数组g[i][j]
对棋盘进行存储数组
a[i]
表示走到最后一格的时候,余k之后为i的情况存不存在,如果存在则置为1,否则为0
vis[i][j][w]
数组用来进行记忆化的操作,含义为搜索到g[i][j]
的时候余k后结果为i的情况存不存在,如果存在就不用继续往下搜了,因为之前已经搜过了
画个图可以更好的理解(记忆化在搜索这类题中很常见,非常重要!!!)
最后的结果输出的就是a[i]==1的那些i,因为题目要求从小到大,所以我又用了一个数组b[i]来存放i,然后用sort函数对b进行排序后输出
深搜代码:
#include <bits/stdc++.h>
using namespace std;
int m,n,k,num;
int ans=1;//ans用来表示搜索到每个位置时的值,因为是相乘不是相加,所以ans必须初始化为1
int g[105][105];
int a[105],b[105];
int vis[105][105][105];
void dfs(int x,int y){
if(x>m || y>n || vis[x][y][(ans*g[x][y])