华为机试题
下面两道题是同学从华为机试回来之后出给我的题目,这里我将自己的解决思路写下来,供相互交流。
题目1:输入一组数,第一个数为num,判断后面数的部分或全部之和是否可以等于第一个数num。
解决思路:假设已经计算了第i个元素之前的数组部分的所有可能的部分和,数目为n个,那么当将第i个元素考虑进来的时候,将增加的可能和为n+1个,其中n个为之前的所有可能和加上a[i-1]的结果,还有一个是只有a[i-1]的部分和a[i-1]。这样一来采用递归的方法,对于有m个元素的数组,部分和为2^m-1个,然后比较这些和与num。
题目2:输入城市数目n,并用矩阵来表示城市之间是否可以到达,矩阵中的元素0表示两城市之间不可到达,1表示可以到达,请计算从起点到终点的所有可行路径数目。
解决思路:这个题目可以通过分治的思想,将题目一点点变小。比如考虑城市a到城市d的路径,可以这样考虑:首先看到d的城市有哪些,如果c城市可以到d,那么就可以转化为求a到c的路径数目,如果b可以到c,那么可以考虑从a到b的可能方法,这样一来就将问题简单化了。使用了递归的思想,代码如下:
1 #include "stdafx.h" 2 #include <iostream> 3 using namespace std; 4 5 bool isMatValid(int **a, int row, int col) 6 { 7 for(int i = 0; i < row; i++) 8 { 9 for(int j = 0; j < col; j++) 10 { 11 if(a[i][j] != a[j][i] && !(a[i][j] == 0 || a[i][j] == 1)) 12 return false; 13 } 14 } 15 return true; 16 } 17 18 int CountNum(int **a, int row, int col) 19 { 20 int count = 0; 21 if(a[row][0] == 1) 22 { 23 count = 1; 24 } 25 26 for(int j = 1; j < col; j++) 27 { 28 if(a[row][j] == 1) 29 { 30 count += CountNum(a, j, j); 31 } 32 } 33 return count; 34 } 35 36 void PrintMatrix(int **a, int row, int col) 37 { 38 for(int i = 0; i < row; i++) 39 { 40 for(int j = 0; j < col; j++) 41 { 42 cout<<a[i][j]<<"\t"; 43 } 44 cout<<endl; 45 } 46 } 47 48 int _tmain(int argc, _TCHAR* argv[]) 49 { 50 int n; 51 cout<<"Please input the number of cities: "; 52 cin>>n; 53 54 int** a = new int*[n]; 55 for(int i = 0; i < n; i++) 56 { 57 a[i] = new int[n]; 58 } 59 60 cout<<"Please input the matrix:"<<endl; 61 for(int i = 0; i < n; i++) 62 { 63 for(int j = 0; j < n; j++) 64 { 65 cin>>a[i][j]; 66 } 67 } 68 69 PrintMatrix(a, n, n); 70 if(isMatValid(a, n, n)) 71 { 72 int count = CountNum(a,n-1, n-1); 73 cout<<"The number of path:\t"<<count<<endl; 74 } 75 else 76 { 77 cout<<"The matrix you input is not valid!"<<endl; 78 } 79 80 system("pause"); 81 return 0; 82 }
Please input the number of cities: 4 Please input the matrix: 1 1 0 1 1 1 1 0 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 0 1 1 1 1 0 1 1 The number of path: 2