Chinaunix首页 | 论坛 | 博客
  • 博客访问: 20928
  • 博文数量: 7
  • 博客积分: 260
  • 博客等级: 入伍新兵
  • 技术积分: 90
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-01 14:57
文章分类

全部博文(7)

文章存档

2012年(7)

最近访客

分类: C/C++

2012-08-06 21:44:26


1.poj 2312
迷宫类问题,用搜索解决。关键在于从起点开始类推到每个点的最短距离,所以搜索的条件要从visit数组变化,即若使到目标点的最少步数减少则将该点放入搜索列表(这个很重要)。关于存储数组我是这么办的,用二维整形数组存,一开始都置0(代表不通行),记得留边界(这样就不怕走出去了)。然后将‘B’付2,‘R'和‘S’不管(还是0),其余付1,这样算法也好写一些。我用的BFS,但我画了个3*3的表从(1,1)到(3,3)感觉好像DFS也可以,没试过。

点击(此处)折叠或打开

  1. #include"stdio.h"
  2. #include"string.h"


  3. struct set
  4. {
  5.     int x;
  6.     int y;
  7. };

  8. struct line
  9. {
  10.     set a[100000];
  11.     int in;
  12.     int out;
  13. };


  14. line L;


  15. void init()
  16. {
  17.     L.in=L.out=0;
  18. }

  19. void in(set e)
  20. {
  21.     if(L.in+1==L.out)
  22.         return;
  23.     L.a[L.in++]=e;
  24.     L.in%=100000;
  25. }

  26. void out(set&e)
  27. {
  28.     if(L.in==L.out)
  29.         return;
  30.     e=L.a[L.out++];
  31.     L.out%=100000;
  32. }

  33.     int least[310][310];
  34.     int pos[310][310];

  35. int main()
  36. {
  37.     set start,end,e,e1;
  38.     int l,c,i,j;
  39.     char ch;
  40.     init();
  41.     scanf("%d%d",&l,&c);
  42.     while(l!=0)
  43.     {
  44.         getchar();
  45.         memset(pos,0,100000);
  46.         for(i=1;i<=l;i++)
  47.         {
  48.             for(j=1;j<=c;j++)
  49.             {
  50.                 pos[i][j]=1;
  51.                 least[i][j]=1000000;
  52.                 scanf("%c",&ch);
  53.                 if(ch=='Y')
  54.                     start.x=i,start.y=j;
  55.                 if(ch=='T')
  56.                     end.x=i,end.y=j;
  57.                 if(ch=='R'||ch=='S')
  58.                     pos[i][j]=0;
  59.                 if(ch=='B')
  60.                     pos[i][j]=2;
  61.             }
  62.             getchar();
  63.         }
  64.         in(start);
  65.         least[start.x][start.y]=0;
  66.         while(L.in!=L.out)
  67.         {
  68.             out(e);
  69.             for(i=1;i<=4;i++)
  70.             {
  71.                 switch(i)
  72.                 {
  73.                 case 1:
  74.                     e1.x=e.x;
  75.                     e1.y=e.y+1;
  76.                     break;
  77.                 case 2:
  78.                     e1.y=e.y;
  79.                     e1.x=e.x+1;
  80.                     break;
  81.                 case 3:
  82.                     e1.x=e.x;
  83.                     e1.y=e.y-1;
  84.                     break;
  85.                 case 4:
  86.                     e1.x=e.x-1;
  87.                     e1.y=e.y;
  88.                     break;
  89.                 }
  90.                 if(pos[e1.x][e1.y]==0)
  91.                     continue;
  92.                 if(least[e.x][e.y]+pos[e1.x][e1.y]<least[e1.x][e1.y])
  93.                 {
  94.                     in(e1);
  95.                     least[e1.x][e1.y]=least[e.x][e.y]+pos[e1.x][e1.y];
  96.                 }
  97.             }
  98.         }
  99.         if(least[end.x][end.y]==1000000)
  100.             printf("-1");
  101.         else
  102.             printf("%d\n",least[end.x][end.y]);
  103.         scanf("%d%d",&l,&c);
  104.         init();
  105.     }
  106. }
 
2.POJ 1321
在一个棋盘上放棋子,每行每列最多只能放一个,且棋盘不规则,问多少种放法。
有点像N皇后问题,变异的有点厉害。区别:1.棋盘不规则 2.没有每斜行不能放两个的规则 3.不一定每行都有棋子(就是这个让我费解了好一会儿)。所以算法也有改变,先保留用一个整型数组表示每列是否有棋子的做法,递归的搜索范围也要扩展到整个二维数组。因为棋子之间没有区别,所以可以每次递归从下一行第一个开始,避免重复,也省略了行重复问题。总的来说简单了些,虽然挺花时间的。

点击(此处)折叠或打开

  1. #include"stdio.h"
  2. #include"string.h"



  3. struct ss
  4. {
  5.     char s[20];
  6. };

  7. ss G[20];

  8. int t[20];
  9. int l;
  10. int N;
  11. int m;


  12. void fun(int n,int p)
  13. {
  14.     if(n>=m)
  15.     {
  16.         N++;
  17.         return;
  18.     }
  19.     int i,j;
  20.     for(i=p;i<=l;i++) for(j=1;j<=l;j++)
  21.         if(G[i].s[j]=='#'&&t[j]==0)
  22.         {
  23.             t[j]=1;
  24.             fun(n+1,i+1);
  25.             t[j]=0;
  26.         }
  27. }


  28. int main()
  29. {
  30.     int i;
  31.     scanf("%d%d",&l,&m);
  32.     getchar();
  33.     while(l!=-1)
  34.     {
  35.         memset(t,0,80);
  36.         for(i=1;i<=l;i++)
  37.             gets(G[i].s+1);
  38.         N=0;
  39.         fun(0,1);
  40.         printf("%d\n",N);
  41.         scanf("%d%d",&l,&m);
  42.         getchar();
  43.     }
  44. }
3.problem G-POJ 2907
从一点出发经过数点后回到该点,确定次序使得总路程最短
问题直接解决有问题,采用深搜递归每当找到所有顶点就计算是否比当前最小值小,若是则改变最小值,否则不变,直到所有方案都结束。

点击(此处)折叠或打开

  1. #include"stdio.h"
  2. #include"string.h"


  3. int leap[200][200];
  4. int color[200][200];
  5. int visit[200][200];
  6. int fn;
  7. int l,c,crnum;


  8. void fun(int n)
  9. {
  10.     int i,j,k,p,q,t;
  11.     for(k=1,i=1;i<=l;i++)
  12.         for(j=1;j<=c;j++)
  13.             if(visit[i][j]==0)
  14.                 k=0;
  15.     if(k==1&&n<fn)
  16.     {
  17.         fn=n;
  18.         return;
  19.     }
  20.     for(i=1;i<=crnum;i++)
  21.     {
  22.         for(j=1;j<=l;j++) for(k=1;k<=c;k++)
  23.             if(color[j][k]==i&&visit[j-1][k]==1&&visit[j][k]==0)
  24.             {
  25.                 for(p=k+1;color[j][p]=color[j][k];p++);
  26.                 for(q=k+1
  27.                 visit[j][k]=1;
  28.                 leap[j][k]=n;
  29.             }
  30.         fun(n+1);
  31.         for(j=1;j<=l;j++) for(k=1;k<=c;k++)
  32.             if(leap[j][k]==n)
  33.                 visit[j][k]=0;
  34.     }
  35. }


  36. int main()
  37. {
  38.     int N,M,x1,y1,x2,y2,cr,i,j;
  39.     scanf("%d",&N);
  40.     while(N--)
  41.     {
  42.         scanf("%d",&M);
  43.         l=0,c=0,crnum=0;
  44.         while(M--)
  45.         {
  46.             scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&cr);
  47.             if(x2>l)
  48.                 l=x2;
  49.             if(y2>c)
  50.                 c=y2;
  51.             if(cr>crnum)
  52.                 crnum=cr;
  53.             for(i=x1+1;i<=x2;i++) for(j=y1+1;j<=y2;j++)
  54.                 color[i][j]=cr;
  55.         }
  56.         memset(visit,0,150000);
  57.         for(i=1;i<200;i++)
  58.             visit[0][i]=1;
  59.         fn=100000;
  60.         fun(0);
  61.         printf("%d\n",fn);
  62.     }
  63. }

problem H  -POJ 2251

迷宫问题:一个三维的空间里,求从起点到终点的最短路程。

同problem A 一样,重要的是一个数组标识从起点到该点的最短距离。只不过是三位的而已。


 

点击(此处)折叠或打开

  1. #include"stdio.h"


  2. struct sss
  3. {
  4.     char s[50][50];
  5. };

  6. struct node
  7. {
  8.     int l,r,c;
  9. };

  10. struct line
  11. {
  12.     node a[30000];
  13.     int in;
  14.     int out;
  15. }L;

  16. void init()
  17. {
  18.     L.in=L.out=0;
  19. }

  20. void in(node e)
  21. {
  22.     if(L.in+1==L.out)
  23.         return;
  24.     L.a[L.in++]=e;
  25.     L.in%=30000;
  26. }

  27. void out(node&e)
  28. {
  29.     if(L.in==L.out)
  30.         return;
  31.     e=L.a[L.out++];
  32.     L.out%=30000;
  33. }

  34. sss G[50];
  35. int least[50][50][50];


  36. int main()
  37. {
  38.     node start,end,e,e1;
  39.     int l,r,c,i,j,k;
  40.     int a[6]={1,-1,0,0,0,0};
  41.     int b[6]={0,0,1,-1,0,0};
  42.     int d[6]={0,0,0,0,1,-1};
  43.     scanf("%d%d%d",&l,&r,&c);
  44.     while(l!=0)
  45.     {
  46.         getchar();
  47.         init();
  48.         for(i=0;i<50;i++) for(j=0;j<50;j++) for(k=0;k<50;k++)
  49.             G[i].s[j][k]='#';
  50.         for(i=1;i<=l;i++)
  51.         {
  52.             for(j=1;j<=r;j++)
  53.             {
  54.                 for(k=1;k<=c;k++)
  55.                 {
  56.                     G[i].s[j][k]=getchar();
  57.                     if(G[i].s[j][k]=='S')
  58.                         start.l=i,start.r=j,start.c=k;
  59.                     if(G[i].s[j][k]=='E')
  60.                         end.l=i,end.r=j,end.c=k;
  61.                 }
  62.                 getchar();
  63.             }
  64.             getchar();
  65.         }
  66.         in(start);
  67.         for(i=1;i<50;i++) for(j=1;j<50;j++) for(k=1;k<50;k++)
  68.             least[i][j][k]=100000;
  69.         least[start.l][start.r][start.c]=0;
  70.         while(L.in!=L.out)
  71.         {
  72.             out(e);
  73.             for(i=0;i<6;i++)
  74.             {
  75.                 e1.l=e.l+a[i];
  76.                 e1.r=e.r+b[i];
  77.                 e1.c=e.c+d[i];
  78.                 if(least[e.l][e.r][e.c]+1<least[e1.l][e1.r][e1.c]&&G[e1.l].s[e1.r][e1.c]!='#')
  79.                 {
  80.                     least[e1.l][e1.r][e1.c]=least[e.l][e.r][e.c]+1;
  81.                     in(e1);
  82.                 }
  83.             }
  84.         }
  85.         if(least[end.l][end.r][end.c]==100000)
  86.             printf("Trapped!\n");
  87.         else
  88.             printf("Escaped in %d minute(s).\n",least[end.l][end.r][end.c]);
  89.         scanf("%d%d%d",&l,&r,&c);
  90.     }

  91. }


problem I -POJ 2708

给一个n*n的有数子宫,可以对每行执行操作(将最后一个变成第一个,其余往右移),使得最大值(每一列的和,其中最大的和)最小。

通过完全模拟,深搜来实现。每次完成一次操作都计算最大值,若最大值小于当前最小值则替换,否则继续,直到全部情况都完成。


点击(此处)折叠或打开

  1. #include"stdio.h"


  2. int G[10][10];
  3. int value[10];
  4. int min;
  5. int c;


  6. void fun(int a[])
  7. {
  8.     int i,t;
  9.     for(i=c,t=a[c];i>=2;i--)
  10.         a[i]=a[i-1];
  11.     a[1]=t;
  12. }


  13. void dfs(int n)
  14. {
  15.     int i,j,m;
  16.     if(n>c)
  17.     {
  18.         for(i=1;i<=c;i++)
  19.             for(j=1,value[i]=0;j<=c;j++)
  20.                 value[i]+=G[j][i];
  21.         m=value[1];
  22.         for(i=2;i<=c;i++)
  23.             if(value[i]>m)
  24.                 m=value[i];
  25.         if(m<min)
  26.             min=m;
  27.         return;
  28.     }
  29.     for(i=1;i<=c;i++)
  30.     {
  31.         if(i!=1)
  32.             fun(G[n]);
  33.         dfs(n+1);
  34.     }
  35. }


  36. int main()
  37. {
  38.     int i,j;
  39.     scanf("%d",&c);
  40.     while(c!=-1)
  41.     {
  42.         for(i=1;i<=c;i++) for(j=1;j<=c;j++)
  43.             scanf("%d",&G[i][j]);
  44.         min=100000;
  45.         dfs(1);
  46.         printf("%d\n",min);
  47.         scanf("%d",&c);
  48.     }
  49. }




阅读(982) | 评论(0) | 转发(0) |
0

上一篇:帮忙看看

下一篇:没有了

给主人留下些什么吧!~~