搜狗笔试题

转自:http://blog.csdn.net/huangxy10/article/details/8071242

搜狗:
1,有n*n个正方形格子,每个格子里有正数或者0,从最左上角往最右下角走,只能向下和向右走。一共走两次,把所有经过的格子的数加起来,求最大值。且两次如果经过同一个格子,则该格子的数只加一次。


思路:

搜索:一共搜(2n-2)步,每一步有四种走法。考虑不相交等条件可以剪去很多枝。

复杂度为O(4^n)


动态规划:

by:绿色夹克衫

详细算法思路:http://www.51nod.com/question/index.html#!questionId=657

s[k][i][j] = max(s[k-1][i-1][j-1],s[k-1][i-1][j],s[k-1][i][j-1],s[k-1][j][i])+map[i][k-i]+map[j][k-j];

复杂度为O(n^3)

  1     #include <iostream>  
  2     #define MAX(a,b) (a)>(b)?(a):(b)  
  3     using namespace std;  
  4       
  5     #define N 5  
  6     int map[5][5]={  
  7         {2,0,8,0,2},  
  8         {0,0,0,0,0},  
  9         {0,3,2,0,0},  
 10         {0,10,0,0,0},  
 11         {2,0,8,0,2}};  
 12     int sumMax=0;  
 13     int p1x=0;  
 14     int p1y=0;  
 15     int p2x=0;  
 16     int p2y=0;  
 17     int curMax=0;  
 18       
 19     /* 
 20     编号系统为: 
 21     00000 
 22     11111 
 23     22222 
 24     33333 
 25     44444 
 26     走1次:编号有:0,1 
 27     走2次:编号有:0,1,2 
 28     走5次:编号有:1,2,3,4 
 29     走k次:编号有:l,l+1,l+2...,h-1 //low,high 的计算见code 
 30     编号到map坐标的转换为: 
 31     编号i,则对应map[i][k-i]. 
 32      
 33     dp方程为: 
 34     s[k][i][j] = max(s[k-1][i-1][j-1],s[k-1][i-1][j],s[k-1][i][j-1],s[k-1][j][i])+map[i][k-i]+map[j][k-j]; 
 35     */  
 36     int dp(void){  
 37         int s[2*N-1][N][N];  
 38         s[0][0][0]=map[0][0];  
 39           
 40         for(int k=1;k<2*N-1;k++){  
 41             int h = k<N?k+1:N;     //走k次后编号上限  
 42             int l = k<N?0:k-N+1;   //走k次后编号下限  
 43             for( int i=l;i<h;i++){  
 44                 for( int j=i+1; j<h; j++){  
 45                         int t=0;  
 46                         if( k==1||i<j-1)  
 47                             t= MAX(t,s[k-1][i][j-1]);  
 48                         if( i-1>=0)  
 49                             t= MAX(t, s[k-1][i-1][j-1]);  
 50                         if( j<h)  
 51                             t= MAX(t, s[k-1][i][j]);  
 52                         if( i-1>=0&&j<h)  
 53                             t= MAX(t, s[k-1][i-1][j]);  
 54                         s[k][i][j]=t+map[i][k-i]+map[j][k-j];  
 55                 }  
 56             }  
 57         }  
 58         return s[2*N-3][N-2][N-1]+map[N-1][N-1];  
 59     }  
 60       
 61     void dfs( int index){  
 62         if( index == 2*N-2){  
 63             if( curMax>sumMax)  
 64                 sumMax = curMax;  
 65             return;  
 66         }  
 67       
 68         if( !(p1x==0 && p1y==0) && !(p2x==N-1 && p2y==N-1))  
 69         {  
 70             if( p1x>= p2x && p1y >= p2y )  
 71                 return;  
 72         }  
 73       
 74         //right right  
 75         if( p1x+1<N && p2x+1<N ){  
 76             p1x++;p2x++;  
 77             int sum = map[p1x][p1y]+map[p2x][p2y];  
 78             curMax += sum;  
 79             dfs(index+1);  
 80             curMax -= sum;  
 81             p1x--;p2x--;  
 82         }  
 83       
 84         //down down  
 85         if( p1y+1<N && p2y+1<N ){  
 86             p1y++;p2y++;  
 87             int sum = map[p1x][p1y]+map[p2x][p2y];  
 88             curMax += sum;  
 89             dfs(index+1);  
 90             curMax -= sum;  
 91             p1y--;p2y--;  
 92         }  
 93       
 94         //rd  
 95         if( p1x+1<N && p2y+1<N ) {  
 96             p1x++;p2y++;  
 97             int sum = map[p1x][p1y]+map[p2x][p2y];  
 98             curMax += sum;  
 99             dfs(index+1);  
100             curMax -= sum;  
101             p1x--;p2y--;  
102         }  
103       
104         //dr  
105         if( p1y+1<N && p2x+1<N ) {  
106             p1y++;p2x++;  
107             int sum = map[p1x][p1y]+map[p2x][p2y];  
108             curMax += sum;  
109             dfs(index+1);  
110             curMax -= sum;  
111             p1y--;p2x--;  
112         }  
113     }  
114       
115     int main()  
116     {  
117         curMax = map[0][0];  
118         dfs(0);  
119         cout <<"搜索结果:"<<sumMax-map[N-1][N-1]<<endl;  
120         cout <<"动态规划结果:"<<dp()<<endl;  
121         return 0;  
122     }  

2,有N个整数(数的大小为0-255)的有序序列,设计加密算法,把它们加密为K个整数(数的大小为0-255),再将K个整数顺序随机打乱,使得可以从这乱序的K个整数中解码出原序列。设计加密解密算法。
有三个子问题:
1,N<=16,要求K<=16*N.
2,N<=16,要求K<=10*N.
3,N<=64,要求K<=15*N.

posted on 2012-12-13 21:04  猿人谷  阅读(263)  评论(0编辑  收藏  举报