一个谷歌面试题

来源:互联网 发布:淘宝运营vip课程 云盘 编辑:程序博客网 时间:2024/05/16 12:17
/*题目要求一个人从西北角出发,走到东南角。他的每一步只能上下左右,不能斜着走入下一个方块。每跨过一个边界的时间为T  (0≤T≤1,000,0000), 每走三步他要休息一下,每个格子的休息时间不一样, 在起点格子不休息,在终点格子有可能会休息。请计算出此人走到终点需要的最短时间。输入格式:先是N, 然后是T,最后是每个格子需要休息时间的数列。例子如下:4 230 92 36 1038 85 60 1641 13 5 6820 97 13 80 输出格式:需要的最短时间。比如对应以上的输入例子,最短时间是31因为对于这个例子,最佳路径是往东走三步,在10 休息,然后往南走两步,往西走一步,在5休息,最后往南往东各走一步到达终点。*/
#include<iostream>using namespace std;#define G 10000//表示正无穷不通路//初始化边长为n*n的邻接矩阵b代表n*n个节点的通路状况void chushihua(int **a,int **b,int n,int t){int i,j,k,m;for(i=0;i<n*n;i++){for(j=0;j<n*n;j++){if(i==j)b[i][j]=0;//对角线为0,自己到自己为0   else b[i][j]=G;//否则初始化为无穷大}}//分别计算n*n个点之间的通路状况for(i=0;i<n;i++){for(j=0;j<n;j++){k=i*n+j;//当前点的序号,如(1,0)的序号为n//m可能到达的节点序号   /*****************************         3       3 0 3     3 0 1 0 3   3 0 1 * 1 2 3     3 0 1 2 3                 3 2 3         3             如上图,*为当前点,0为不可达,他的可能到达点为上述1,3所示的点,such as( *->1->*->1)2为特殊情况,当前为终点是才可达,其中右下角2个1也可能直达终点要考虑*/if(j-1>=0){   //左1点m=k-1;b[k][m]=a[i][j-1]+3*t;}if(i-1>=0){//上1点m=k-n;b[k][m]=a[i-1][j]+3*t;}if(j+1<n){//右1点m=k+1;if(j+1==n-1&&i==n-1)b[k][m]=t;else b[k][m]=a[i][j+1]+3*t;}if(i+1<n){//下1点m=k+n ;if(j==n-1&&i+1==n-1)b[k][m]=t;else b[k][m]=a[i+1][j]+3*t;}//******************************if(j-3>=0){//左3m=k-3;b[k][m]=a[i][j-3]+3*t;}if(j+3<n){//右3m=k+3;              b[k][m]=a[i][j+3]+3*t;}if(i-3>=0){//上3m=(i-3)*n+j;b[k][m]=a[i-3][j]+3*t;}if(i+3<n){//下3m=(i+3)*n+j;b[k][m]=a[i+3][j]+3*t;}//*************************if(j-2>=0&&i-1>=0){//左2上1m=(i-1)*n+j-2;   b[k][m]=a[i-1][j-2]+3*t;}            if(j-2>=0&&i+1<n){//左2下1m=(i+1)*n+j-2;                b[k][m]=a[i+1][j-2]+3*t;}if(j+2<n&&i-1>=0){//右2上1m=(i-1)*n+j+2;b[k][m]=a[i-1][j+2]+3*t;}if(j+2<n&&i+1<n){//右2下1m=(i+1)*n+j+2;b[k][m]=a[i+1][j+2]+3*t;}//*****************************if(j-1>=0&&i-2>=0){//左1上2m=(i-2)*n+j-1;b[k][m]=a[i-2][j-1]+3*t;}if(j-1>=0&&i+2<n){//左1下2                m=(i+2)*n+j-1;b[k][m]=a[i+2][j-1]+3*t;}if(j+1<n&&i-2>=0){//右1上2m=(i-2)*n+j+1;b[k][m]=a[i-2][j+1]+3*t;}if(j+1<n&&i+2<n){//右1下2m=(i+2)*n+j+1;   b[k][m]=a[i+2][j+1]+3*t;}            //****************************if(i+2==n-1&&j==n-1){//下2到终点m=(i+2)*n+j;b[k][m]=2*t;}if(i+1==n-1&&j+1==n-1)            {//下1右1到终点m=(i+1)*n+j+1;b[k][m]=2*t;}if(i==n-1&&j+2==n-1){//右2到终点m=k+2;b[k][m]=2*t;}}}cout<<"邻接矩阵b为:\n";for(i=0;i<n*n;i++){for(j=0;j<n*n;j++)if(b[i][j]==G) cout<<b[i][j]<<" ";        else cout<<b[i][j]<<"      ";cout<<endl;}}int choose(int *d,bool *s,int n){int i,minpos,min;min=G;minpos=-1;for(i=0;i<n;i++)if(d[i]<=min&&!s[i]){ min=d[i]; minpos=i;}return minpos;}//此处n=N*N,  迪杰斯特拉算法void Dijkstra(int v,int *d,int *path,int n,int **a,int **raw,int N){int i,k,w;if(v<0||v>n-1)cout<<"Error!"<<endl;bool *s=new bool[n];for(i=0;i<n;i++){ s[i]=false; d[i]=a[v][i]; if(i!=v&&d[i]<G)path[i]=v; else path[i]=-1;}s[v]=true;d[v]=0;for(i=1;i<n;i++){k=choose(d,s,n);s[k]=true;for(w=0;w<n;w++)if(!s[w]&&d[k]+a[k][w]<d[w]){  d[w]=d[k]+a[k][w];  path[w]=k;}}cout<<"最短时间:"<<d[n-1]<<endl;   /*0到所有点的最短路径for(i=0;i<n;i++)cout<<"path["<<i<<"]="<<path[i]<<" "<<"d["<<i<<"]="<<d[i]<<endl;*///起点0到终点n-1的路径    cout<<"起点号0到终点号n-1的路径为:"<<endl;int *z=new int[n];for(i=0;i<n;i++)z[i]=-1;for(w=n-1,i=n-1;w>0;w=path[w],i--)z[i]=path[w]; for(i;i<n;i++){if(z[i]!=-1){ int x=z[i], col,row;         col=x%N;     row=(x-col)/N;cout<<"("<<row<<","<<col<<")"<<"方格值"<<raw[row][col]<<endl;}}cout<<"("<<N-1<<","<<N-1<<") 方格值"<<raw[N-1][N-1]<<endl;}int main(){  int N,T,i,j;  cin>>N>>T;  int **a=new int*[N];  int **b=new int*[N*N];   for(i=0;i<N*N;i++) b[i]=new int[N*N];  for(i=0;i<N;i++) a[i]=new int[N];  for(i=0;i<N;i++) for(j=0;j<N;j++) cin>>a[i][j];  cout<<"矩阵a:"<<endl;  for(i=0;i<N;i++)  { for(j=0;j<N;j++)   cout<<a[i][j]<<" "; cout<<endl;  }  chushihua(a,b,N,T);  int *path=new int[N*N];  int *d=new int[N*N];   Dijkstra(0,d,path,N*N,b,a,N);      for(i=0;i<N;i++){       delete *a;   }   for(i=0;i<N*N;i++){       delete *a;   }   delete a;   delete b;  //测试dijkstra/* int i,j;  int *path=new int[6];  int *d=new int[6];  int **ad=new int*[6];  for(i=0;i<6;i++) ad[i]=new int[6];  for(i=0;i<6;i++)  for(j=0;j<6;j++)  { if(i==j) ad[i][j]=0; else ad[i][j]=G;  }  ad[0][1]=50;  ad[0][2]=10;  ad[0][4]=70;  ad[1][2]=15;  ad[1][4]=10;  ad[2][0]=20;  ad[2][3]=15;  ad[3][1]=20;  ad[3][4]=35;  ad[4][3]=30;  ad[5][3]=3;  for(i=0;i<6;i++)  {     for(j=0;j<6;j++)cout<<ad[i][j]<<" ";cout<<endl;  }  Dijkstra(0,d,path,6,ad);  */  return 0;}