Description
有一个n*n的正整数矩阵,要你求一条从第一行第一列的格子到第n行第n列的路,使得你走过的格子里面的数乘起来的值末尾的零的个数最小。输出最小个数。
Input
第一行包含1个数n。
接下来n行每行n个数字。
Output
一个数字表示末尾零最小个数。
Sample Input
3
1 2 3
4 5 6
7 8 9
Sample Output
0
HINT
Source
末尾0的个数只看2,5的个数,直接暴搜得到最终答案
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <list>
#include <algorithm>
#include <climits>
using namespace std;
#define lson 2*i
#define rson 2*i+1
#define LS l,mid,lson
#define RS mid+1,r,rson
#define UP(i,x,y) for(i=x;i<=y;i++)
#define DOWN(i,x,y) for(i=x;i>=y;i--)
#define MEM(a,x) memset(a,x,sizeof(a))
#define W(a) while(a)
#define gcd(a,b) __gcd(a,b)
#define LL long long
#define N 1005
#define INF 0x3f3f3f3f
#define EXP 1e-8
#define lowbit(x) (x&-x)
const int mod = 1e9+7;
struct node
{
int x,y;
};
int a[N][N][2];
int vis[N][N];
int to[4][2]= {0,1,1,0,-1,0,0,-1};
int dis[N][N][2][2],n;
void bfs()
{
memset(dis,INF,sizeof(dis));
queue<node> q;
node s,nex;
memset(vis,0,sizeof(vis));
s.x =1;
s.y = 1;
q.push(s);
vis[s.x][s.y] = 1;
if(a[1][1][0]<=a[1][1][1])
{
dis[1][1][0][0] = a[1][1][0];//2的个数比较少时2的个数
dis[1][1][0][1] = a[1][1][1];//2的个数比较少时5的个数
}
else
{
dis[1][1][1][0] = a[1][1][0];//5的个数比较少时2的个数
dis[1][1][1][1] = a[1][1][1];//5的个数比较少时5的个数
}
while(!q.empty())
{
s = q.front();
q.pop();
int i,j,k;
for(i = 0; i<4; i++)
{
nex.x = s.x+to[i][0];
nex.y = s.y+to[i][1];
if(nex.x<1||nex.y<1||nex.x>n||nex.y>n)
continue;
for(j = 0; j<2; j++)
{
int cnt2 = dis[s.x][s.y][j][0]+a[nex.x][nex.y][0];
int cnt5 = dis[s.x][s.y][j][1]+a[nex.x][nex.y][1];
if(cnt2<=cnt5 && cnt2<dis[nex.x][nex.y][0][0])
{
dis[nex.x][nex.y][0][0] = cnt2;
dis[nex.x][nex.y][0][1] = cnt5;
if(!vis[nex.x][nex.y])
{
vis[nex.x][nex.y] = 1;
q.push(nex);
}
}
else if(cnt2>cnt5 && cnt5<dis[nex.x][nex.y][1][1])
{
dis[nex.x][nex.y][1][0] = cnt2;
dis[nex.x][nex.y][1][1] = cnt5;
if(!vis[nex.x][nex.y])
{
vis[nex.x][nex.y] = 1;
q.push(nex);
}
}
}
}
}
}
int main()
{
int i,j,x;
while(~scanf("%d",&n))
{
memset(a,0,sizeof(a));
memset(dis,0,sizeof(dis));
for(i = 1; i<=n; i++)
{
for(j = 1; j<=n; j++)
{
int cnt2 = 0,cnt5 = 0;
scanf("%d",&x);
while(x%2==0)
{
cnt2++;
x/=2;
}
while(x%5==0)
{
cnt5++;
x/=5;
}
a[i][j][0] = cnt2;
a[i][j][1] = cnt5;
}
}
bfs();
printf("%d\n",min(dis[n][n][0][0],dis[n][n][1][1]));
}
return 0;
}