练习71

  1. /******************************************************************************
  2. 71. (最长连线) 设有一个 N×N 的方格图形,且 N 为 3 的倍数。要求在图形中
  3.  存放 0 或 1,相邻的 1 可以连成一条连线,连接的方法可以是行,也可以是列;
  4.  同时约定一条连线只能有一个起点和一个终点,图形上的点最多只能访问一次。
  5.  编程求最长连线. 例如 N=6 时,有下图:
  6.                  1  2  3  4  5  6
  7.                ┌─┬─┬─┬─┬─┬─┐
  8.            1  │1│1│1│0│0│1│
  9.                ├─┼─┼─┼─┼─┼─┤
  10.            2  │1│1│0│1│1│1│
  11.                ├─┼─┼─┼─┼─┼─┤
  12.            3  │0│0│0│1│0│1│
  13.                ├─┼─┼─┼─┼─┼─┤
  14.            4  │1│1│0│1│1│1│
  15.                ├─┼─┼─┼─┼─┼─┤
  16.            5  │0│1│0│0│0│0│
  17.                ├─┼─┼─┼─┼─┼─┤
  18.            6  │1│1│1│1│0│0│
  19.                └─┴─┴─┴─┴─┴─┘
  20.    在该图中,包含有如下的一些连线:
  21.      1←1←1        1←1                     1
  22.      ↓                ↓                         ↓
  23.      1→1            1                 1→1  1
  24.                        ↓                 ↑      ↓
  25.                        1→1→1         1      1
  26.                                           ↑      ↓
  27.                                           1←1←1
  28.     在以上的连线中,最长的连线为:    表示方法:
  29.              1                       最长连线长度:LMAX=9
  30.              ↓                       连线:(1,6)→(2,6)→
  31.      1→1  1                             (3,6)→(4,6)→
  32.      ↑      ↓                             (4,5)→(4,4)→
  33.      1      1                             (3,4)→(2,4)→
  34.      ↑      ↓                             (2,5)
  35.      1←1←1                  连线的表示不是唯一的,仅给出一种即可。
  36.   *****************************************************************************/
  37. /*
  38. //分治法求解
  39. #include <stdio.h>
  40. typedef struct
  41. {
  42.     int x;
  43.     int y;
  44. } Pos;
  45. #define N 6
  46. int dx[] = {1,0,-1,0};
  47. int dy[] = {0,1,0,-1};
  48. int map[N][N] = {1,1,1,0,0,1,
  49.                  1,1,0,1,1,1,
  50.                  0,0,0,1,0,1,
  51.                  1,1,0,1,1,1,
  52.                  0,1,0,0,0,0,
  53.                  1,1,1,1,0,0};
  54. Pos Line[N*N];
  55. Pos MaxLine[N*N];
  56. //连线
  57. void join(int x, int y, int k, int *pmax)
  58. {
  59.     int i;  
  60.     Line[k].x = x;
  61.     Line[k].y = y;
  62.     map[y][x] = 0;
  63.     for(i=0; i<4; i++)//分治
  64.     {   
  65.         #define CHECKED(x,y) x>=0 && x<N && y>=0 && y<N && map[y][x] == 1
  66.         if(CHECKED(x+dx[i],y+dy[i]))
  67.         {
  68.             join(x+dx[i],y+dy[i],k+1,pmax);
  69.         }
  70.     }
  71.     map[y][x] = 1;
  72.     //找到一条路径
  73.     if(k+1 > *pmax)
  74.     {
  75.         int t;
  76.         *pmax = k+1;
  77.         for(t=0; t<=*pmax; t++)
  78.             MaxLine[t] = Line[t];
  79.     }
  80. }
  81. //打印路径
  82. void PrintMaxLine(int max)
  83. {
  84.     int i;
  85.     printf("max = %d/n",max);
  86.     for(i=0; i<max; i++)
  87.     {
  88.         printf("(%d , %d) ",MaxLine[i].x+1,MaxLine[i].y+1);
  89.     }   
  90.     printf("/n");
  91. }
  92. void main()
  93. {
  94.     int x,y;
  95.     int max = 0;
  96.     for(y=0; y<N; y++)
  97.     {
  98.         for(x=0; x<N; x++)
  99.         {
  100.             if(map[y][x] == 1)
  101.                 join(x,y,0,&max);       
  102.         }
  103.     }
  104.     PrintMaxLine(max);
  105. }
  106. */
  107. //用回溯法求解
  108. #include <stdio.h>
  109. typedef struct
  110. {
  111.     int x;
  112.     int y;
  113. } Pos;
  114. #define N 6
  115. int dx[] = {1,0,-1,0};
  116. int dy[] = {0,1,0,-1};
  117. int map[N][N] = {1,1,1,0,0,1,
  118.                  1,1,0,1,1,1,
  119.                  0,0,0,1,0,1,
  120.                  1,1,0,1,1,1,
  121.                  0,1,0,0,0,0,
  122.                  1,1,1,1,0,0};
  123. Pos Line[N*N];
  124. Pos MaxLine[N*N];
  125. int path[N*N];
  126. int join(int x, int y)
  127. {
  128.     int k;
  129.     int max = 0;
  130.     if(map[y][x] == 0)
  131.         return 0;
  132.     Line[0].x = x;
  133.     Line[0].y = y;
  134.     for(k=0; k<N*N; k++)
  135.         path[k] = -1;
  136.     
  137.     map[y][x] = 0;
  138.     k = 0;
  139.     while(k>=0)
  140.     {
  141.         while(++path[k]<4)
  142.         {
  143.             int tx,ty;
  144.             tx = x + dx[path[k]];
  145.             ty = y + dy[path[k]];
  146.             if(tx>=0 && tx<N && ty>=0 && ty<N && map[ty][tx] == 1)
  147.             {
  148.                 map[y][x] = 0;
  149.                 x = tx;
  150.                 y = ty;
  151.                 k++;
  152.             }
  153.         }
  154.         //找到从该点出发的一条路径
  155.         if(max < k)//如果大于当前最大长度,保存
  156.         {
  157.             int i;
  158.             max = k;
  159.             for(i=0; i<max; i++)
  160.             {
  161.                 //保存从该点出发的最长路径
  162.                 Line[i+1].x = Line[i].x + dx[path[i]];
  163.                 Line[i+1].y = Line[i].y + dy[path[i]];
  164.             }
  165.         }
  166.         //回溯
  167.         map[y][x] = 1;
  168.         path[k] = -1;
  169.         k--;
  170.         if(k<0)
  171.         {
  172.             break;
  173.         }
  174.         x = x - dx[path[k]];
  175.         y = y - dy[path[k]];
  176.     }
  177.     map[y][x] = 1;
  178.     return max;
  179. }
  180. void PrintMaxLine(int max)
  181. {
  182.     int i;
  183.     printf("max = %d/n",max+1);
  184.     for(i=0; i<=max; i++)
  185.     {
  186.         printf("(%d,%d) ",MaxLine[i].x+1,MaxLine[i].y+1);
  187.     }
  188.     printf("/n");
  189. }
  190. void main()
  191. {
  192.     int len;
  193.     int x, y;
  194.     int max = 0;
  195.     for(y=0; y<N; y++)
  196.     {
  197.         for(x=0; x<N; x++)
  198.         {
  199.                 len = join(x,y);
  200.                 if(max < len)
  201.                 {
  202.                     int i;
  203.                     max = len;
  204.                     for(i=0; i<=max; i++)
  205.                         MaxLine[i] = Line[i];
  206.                 }
  207.         }
  208.     }
  209.     PrintMaxLine(max);  
  210. }
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值