[关闭]
@yudesong 2017-06-24T16:18:56.000000Z 字数 4547 阅读 616

经典算法题

经典算法题


1. 经典迷宫问题

给定一个迷宫,入口为左上角,出口为右下角,问是否有路径从入口到出口,若有则输出一条这样的路径。注意移动可以从上、下、左、右、上左、上右、下左、下右八个方向进行。迷宫输入0表示可走,输入1表示墙。易得可以用1将迷宫围起来避免边界问题。

参考代码:

  1. #include <stdio.h>
  2. int visit(int i , int j);
  3. int maze[7][7] = {
  4. {2,2,2,2,2,2,2},
  5. {2,0,0,0,0,0,2},
  6. {2,0,2,0,2,0,2},
  7. {2,0,0,2,0,2,2},
  8. {2,2,0,2,0,2,2},
  9. {2,0,0,0,0,0,2},
  10. {2,2,2,2,2,2,2},
  11. };
  12. int si = 1 , sj = 1 ;
  13. int ei = 5 , ej = 5 ;
  14. int success = 0 ;
  15. int main()
  16. {
  17. int i , j ;
  18. printf("Display the maze :\n");
  19. for(i = 0 ; i < 7 ; i++)
  20. {
  21. for(j = 0 ; j < 7 ; j++)
  22. {
  23. if(maze[i][j] == 2)
  24. {
  25. printf("■");
  26. }
  27. else
  28. {
  29. printf(" ");
  30. }
  31. }
  32. printf("\n");
  33. }
  34. if(visit(si , sj) == 0)
  35. {
  36. printf("\nNot found exit !");
  37. }
  38. else
  39. {
  40. printf("Display the maze :\n");
  41. for(i = 0 ; i < 7 ; i++)
  42. {
  43. for(j = 0 ; j < 7 ; j++)
  44. {
  45. if(maze[i][j] == 2)
  46. {
  47. printf("■");
  48. }
  49. else if(maze[i][j] == 1)
  50. {
  51. printf("◇");
  52. }
  53. else
  54. {
  55. printf(" ");
  56. }
  57. }
  58. printf("\n");
  59. }
  60. }
  61.    return 0 ;
  62. }
  63. int visit(int i , int j)
  64. {
  65. maze[i][j] = 1 ;
  66. if(i == ei && j == ej)
  67. success = 1 ;
  68. if(success != 1 && maze[i][j + 1] == 0)
  69. visit(i , j + 1);
  70. if(success != 1 && maze[i + 1][j] == 0)
  71. visit(i + 1 , j);
  72. if(success != 1 && maze[i - 1][j] == 0)
  73. visit(i - 1 , j);
  74. if(success != 1 && maze[i][j - 1] == 0)
  75. visit(i , j - 1);
  76. if(success != 1)
  77. maze[i][j] == 0 ;
  78. return success ;
  79. }
2. 大数相乘问题
  1. void reverseOrder(char* str, int p, int q)
  2. {
  3. char temp;
  4. while(p < q)
  5. {
  6. temp = str[p];
  7. str[p] = str[q];
  8. str[q] = temp;
  9. p ++;
  10. q --;
  11. }
  12. }
  13. char* multiLargeNum(char* A, char* B)
  14. {
  15. int m = strlen(A);
  16. int n = strlen(B);
  17. char* result = new char[m+n+1];
  18. memset(result, '0', m+n);
  19. result[m+n] = '\0';
  20. reverseOrder(A, 0, m-1);
  21. reverseOrder(B, 0, n-1);
  22. int multiFlag; // 乘积进位
  23. int addFlag; // 加法进位
  24. for(int i=0; i <= n-1; i++) // B的每一位
  25. {
  26. multiFlag = 0;
  27. addFlag = 0;
  28. for(int j=0; j <= m-1; j++) // A的每一位
  29. {
  30. // '0' - 48 = 0
  31. int temp1 = (A[j] - 48) * (B[i] - 48) + multiFlag;
  32. multiFlag = temp1 / 10;
  33. temp1 = temp1 % 10;
  34. int temp2 = (result[i+j] - 48) + temp1 + addFlag;
  35. addFlag = temp2 / 10;
  36. result[i+j] = temp2 % 10 + 48;
  37. }
  38. result[i + m] += multiFlag + addFlag;
  39. }
  40. reverseOrder(result, 0, m+n-1); // 逆序回来
  41. return result;
  42. }
  43. int main()
  44. {
  45. char A[] = "962346239843253528686293234124";
  46. char B[] = "93459382645998213649236498";
  47. char *res = multiLargeNum(A, B);
  48. if(res[0] != 48)
  49. printf("%c", res[0]);
  50. printf("%s", res+1);
  51. delete [] res;
  52. return 0;
  53. }
3. 大数相加
  1. #include<stdio.h>
  2. #include<string.h>
  3. #define Max 101
  4. void print(char sum[]);
  5. void bigNumAdd(char a[],char b[],char sum[]);
  6. int main()
  7. {
  8. char a[Max];
  9. char b[Max];
  10. char sum[Max];
  11. gets(a);
  12. gets(b);
  13. bigNumAdd(a,b,sum);
  14. print(sum);
  15. return 0;
  16. }
  17. void bigNumAdd(char a[],char b[],char sum[])
  18. {
  19. int i=0;
  20. int c=0;//表示进位
  21. //初始化,对以后位运算有很大帮助!
  22. char m[Max]={0};
  23. char n[Max]={0};
  24. memset(sum,0,Max*sizeof(char)); //这里不能写成memset(sum,0,sizeof(sum));原因见注意事项1
  25. //字符串反转且字符串变数字
  26. int lenA=strlen(a);
  27. int lenB=strlen(b);
  28. for (i=0;i<lenA;i++)
  29. {
  30. m[i]=a[lenA-i-1]-'0';
  31. }
  32. for (i=0;i<lenB;i++)
  33. {
  34. n[i]=b[lenB-i-1]-'0';
  35. }
  36. //位运算
  37. for (i=0;i<lenA||i<lenB;i++)
  38. {
  39. sum[i]=(m[i]+n[i]+c)%10+'0';//得到末位
  40. c=(m[i]+n[i]+c)/10;//得到进位
  41. }
  42. }
  43. void print(char sum[])
  44. {
  45. int i=0;
  46. int j=0;
  47. int len = strlen(sum);
  48. for (i=len-1;sum[i]==0;i--); //找到第一个不为零的位置,方便输出
  49. for (j=i;j>=0;j--)
  50. {
  51. printf("%c",sum[j]);
  52. }
  53. }
4. 八皇后问题
  1. #include <iostream>
  2. #include <math.h>
  3. using namespace std;
  4. const int N=20;
  5. int q[N];
  6. int count=0;
  7. void display()
  8. {
  9. count++;
  10. int i;
  11. for(i=1;i<=6;i++)
  12. cout<<q[i]<<" ";
  13. cout<<endl;
  14. }
  15. bool find(int i,int j)
  16. {
  17. int m=1;
  18. while(m<j)
  19. {
  20. if((q[m]==i) || abs(q[m]-i)==abs(m-j))
  21. return false;
  22. m++;
  23. }
  24. return true;
  25. }
  26. void place(int i,int n)
  27. {
  28. if(i>n) display();
  29. else
  30. {
  31. int j;
  32. for(j=1;j<=n;j++)
  33. {
  34. if(find(j,i))
  35. {
  36. q[i]=j;
  37. place(i+1,n);
  38. }
  39. }
  40. }
  41. }
  42. int main()
  43. {
  44. place(1,6);
  45. return 0;
  46. }
5. 旅行商问题
  1. #include<iostream>
  2. #include<iomanip>
  3. using namespace std;
  4. int n;
  5. int cost[20][20]={};
  6. bool done[20]={1};
  7. int start = 0; //从城市0开始
  8. int imin(int num, int cur)
  9. {
  10. if(num==1) //递归调用的出口
  11. return cost[cur][start];
  12. //所有节点的最后一个节点,最后返回 最后一个节点到起点的路径
  13. int mincost = 10000;
  14. for(int i=0; i<n; i++)
  15. {
  16. cout<<i<<" i:"<<done[i]<<endl;
  17. if(!done[i] && i!=start) //该结点没加入 且 非起始点
  18. {
  19. if(mincost <= cost[cur][i]+cost[i][start])
  20. {
  21. continue;
  22. //其作用为结束本次循环。即跳出循环体中下面尚未执行的语句。区别于break
  23. }
  24. done[i] = 1; //递归调用时,防止重复调用
  25. int value = cost[cur][i] + imin(num-1, i);
  26. if(mincost > value)
  27. {
  28. mincost = value;
  29. }
  30. done[i] = 0;//本次递归调用完毕,让下次递归调用
  31. }
  32. }
  33. return mincost;
  34. }
  35. int main()
  36. {
  37. // cin >> n;
  38. n=4;
  39. int cc[4][4]={{0 ,4, 1, 3},
  40. {4 ,0 ,2, 1},
  41. {1 ,2 ,0, 5},
  42. {3 ,1, 5, 0}};
  43. for(int i=0; i<n; i++)
  44. {
  45. for(int j=0; j<n; j++)
  46. {
  47. //cin >> cost[i][j];
  48. cost[i][j]=cc[i][j];
  49. }
  50. }
  51. cout << imin(n, start) << endl;
  52. return 0;
  53. }
6. 0/1背包问题
  1. int V[200][200];
  2. //前i个物品装入容量为j的背包中获得的最大价值
  3. int max(int a,int b)
  4. {
  5. if(a>=b)
  6. return a;
  7. else return b;
  8. }
  9. int KnapSack(int n,int w[],int v[],int x[],int C)
  10. {
  11. int i,j;
  12. for(i=0;i<=n;i++)
  13. V[i][0]=0;
  14. for(j=0;j<=C;j++)
  15. V[0][j]=0;
  16. for(i=0;i<=n-1;i++)
  17. for(j=0;j<=C;j++)
  18. if(j<w[i])
  19. V[i][j]=V[i-1][j];
  20. else
  21. V[i][j]=max(V[i-1][j],V[i-1][j-w[i]]+v[i]);
  22. j=C;
  23. for(i=n-1;i>=0;i--)
  24. {
  25. if(V[i][j]>V[i-1][j])
  26. {
  27. x[i]=1;
  28. j=j-w[i];
  29. }
  30. else
  31. x[i]=0;
  32. }
  33. printf("选中的物品是:\n");
  34. for(i=0;i<n;i++)
  35. printf("%d ",x[i]);
  36. printf("\n");
  37. return V[n-1][C];
  38. }
  39. void main()
  40. {
  41. int s;//获得的最大价值
  42. int w[15];//物品的重量
  43. int v[15];//物品的价值
  44. int x[15];//物品的选取状态
  45. int n,i;
  46. int C;//背包最大容量
  47. n=5;
  48. printf("请输入背包的最大容量:\n");
  49. scanf("%d",&C);
  50. printf("输入物品数:\n");
  51. scanf("%d",&n);
  52. printf("请分别输入物品的重量:\n");
  53. for(i=0;i<n;i++)
  54. scanf("%d",&w[i]);
  55. printf("请分别输入物品的价值:\n");
  56. for(i=0;i<n;i++)
  57. scanf("%d",&v[i]);
  58. s=KnapSack(n,w,v,x,C);
  59. printf("最大物品价值为:\n");
  60. printf("%d\n",s);
  61. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注