• 2014H-Star初赛题解


     

    2014H-Star初赛题解

    分类: ACM HHUC2014-04-19 11:17 110人阅读 评论(0) 收藏 举报

    A.不要被阶乘吓倒

    题型:数学

    题意:

    给你数字N(0<=N<=10000),让你求出N!末尾的零的个数

     

    思路:

    此题为编程之美书上的题目

     

    一些初学者可能不知道什么是多组输入,即输入直到测试数据文件的末尾

    while(cin >> n) || while(scanf("%d", &n) != EOF)均可实现以上功能

     

    然后我们来数阶乘末尾的0,有参赛选手选用直接模拟用来统计最后零的个数,但大家可以大致测试一下,10000!是多少位数的(我用Python测试为35660位)。一般来说,1S的时限允许进行百万级别(即小于一千万)的循环

     

    末尾1个0则必然出现了1个10。10只有两个因子构成(2*5)。所以我们只需要统计N!中出现a个2,出现b个5,取min(a,b)即可。然而我们可以很清楚地发现到2出现的频率是远大于5出现的频率的。从数学期望上来说,任意一个数有1/2的概率含有因子2,而只有1/5的概率含有因子5。因此我们只需要统计N!中5出现的个数。所有5的倍数出现1次,25的倍数在5的基础上再出现一次(25 = 5 * 5)

     

    代码:/*代码来自Assassin*/

    [cpp] view plaincopy

    1. #include <iostream>  
    2.   
    3. using namespace std;  
    4.   
    5. int main()  
    6. {  
    7.     int n;  
    8.     while(cin >> n){  
    9.         cout << (n/5 + n/25 + n/125 + n/625 + n/3125) << endl;  
    10. 10.     }  
    11. 11.     return 0;  

    12. }  

     

    B.Cow Pedigrees

    题型:动态规划

    题意:

    农民约翰准备购买一群新奶牛。 在这个新的奶牛群中, 每一个母亲奶牛都生两个小奶牛。这些奶牛间的关系可以用二叉树来表示。这些二叉树总共有N个节点(3 <= N < 200)。这些二叉树有如下性质:

    每一个节点的度是0或2。度是这个节点的孩子的数目。

    树的高度等于K(1 < K < 100)。高度是从根到最远的那个叶子所需要经过的结点数; 叶子是指没有孩子的节点。

    有多少不同的家谱结构? 如果一个家谱的树结构不同于另一个的, 那么这两个家谱就是不同的。输出可能的家谱树的个数除以9901的余数。

    思路:

    这是一个DP问题。我们所关心的树的性质是深度和节点数,所以我们可以做这样一张表:table[i][j]表示深度为i、节点数为j的树的个数。根据给定的约束条件,j必须为奇数。你如何构造一棵树呢?当然是由更小的树来构造了。一棵深度为i、节点数为j的树可以由两个子树以及一个根结点构造而成。当i、j已经选定时,我们选择左子树的节点数k。这样我们也就知道了右子树的节点数,即j-k-1。至于深度,至少要有一棵子树的深度为i-1才能使构造出的新树深度为i。有三种可能的情况:左子树深度为i-1 ,右子树深度小于i-1;右子树深度为i-1,左子树深度小于i-1;左右子树深度都为i-1。事实上,当我们在构造一棵深度为i的树时,我们只关心使用的子树深度是否为i-1或更小。因此,我们使用另一个数组smalltrees[i-2][j]记录所有深度小于i-1的树,而不仅仅是深度为i-2的树。知道了上面的这些,我们就可以用以下三种可能的方法来建树了:

    table[i][j] := smalltrees[i-2][k]*table[i-1][j-1-k];

                      // 左子树深度小于i-1,右子树深度为i-1

    table[i][j] := table[i-1][k]*smalltrees[i-2][j-1-k];

                      // 左子树深度为i-1,右子树深度小于i-1

    table[i][j] := table[i-1][k]*table[i-1][j-1-k];

                      // 左右子树深度都为i-1

    代码:/*代码来自NOCOW*/

    [cpp] view plaincopy

    1. #include <cstdio>  
    2. #include <cstdlib>  
    3. #define MOD 9901  
    4. using namespace std;  
    5.   
    6. int table[101][202],N,K,c;  
    7. int smalltrees[101][202];  
    8.   
    9. int main() {  
    10. 10.     scanf("%d %d",&N,&K);  
    11. 11.     table[1][1]=1;  
    12. 12.     for (int i=2;i<=K;i++) {  
    13. 13.         for (int j=1;j<=N;j+=2)  
    14. 14.             for (int k=1;k<=j-1-k;k+=2) {  
    15. 15.                 if (k!=j-1-k) c=2; else c=1;  //判断树的结构是否对称  
    16. 16.                 table[i][j]+=c*(  
    17. 17.                         smalltrees[i-2][k]*table[i-1][j-1-k]  // 左子树深度小于i-1  
    18. 18.                         +table[i-1][k]*smalltrees[i-2][j-1-k]  // 右子树深度小于i-1  
    19. 19.                         +table[i-1][k]*table[i-1][j-1-k]);// 都为i-1  
    20. 20.                 table[i][j]%=MOD;  
    21. 21.             }  
    22. 22.         for (int k=0;k<=N;k++) {  
    23. 23.         // 确保接下来第i次迭代中的smalltrees[i-2][j]包含了深度小于i-1且节点数为j的树的个数  
    24. 24.             smalltrees[i-1][k]+=table[i-1][k]+smalltrees[i-2][k];  
    25. 25.             smalltrees[i-1][k]%=MOD;  
    26. 26.         }  
    27. 27.     }  
    28. 28.   
    29. 29.     printf ("%d ",table[K][N]);  
    30. 30.     return 0;  

    31. }  

     

     

    C.回文素数

    题型:构造

    题意:

    找出范围[a,b](5 <= a < b <= 100,000,000)( 一亿)间的所有回文质数(回文又是素数);

    思路:

    这道题有两种思路:

    1. 用筛法求出1..1e8范围内的素数,然后判断每个素数是否是回文数。
    2. 生成1..1e8范围内的回文数,然后判断它是否是素数。

    思路1的复杂度是O(n),思路2的复杂度是O(√n*√n)=O(n),从复杂度来看两种思路没有差别。但思路1用筛法用素数要开O(n)的数组,在n=1e8是就是90M,超出了空间限制,(而且有可能超时),而思路2的空间复杂度是O(1)的,所以我们用思路2。

    [cpp] view plaincopy

    1. //产生长度为5的回文数  
    2.  for (d1 = 1; d1 <= 9; d1+=2) {  // 只有奇数才会是素数  
    3.      for (d2 = 0; d2 <= 9; d2++) {  
    4.          for (d3 = 0; d3 <= 9; d3++) {  
    5.            palindrome = 10000*d1 + 1000*d2 +100*d3 + 10*d2 + d1;//(处理回文数...)  
    6.          }  
    7.      }  
    8.  }  

    代码:/*代码来自NOCOW*/

    [cpp] view plaincopy

    1. #include<cstdio>  
    2. #include<cstdlib>  
    3. #include<cstring>  
    4. #include<cmath>  
    5.   
    6. int A,B;  
    7. int answer[100000];  
    8. int numAnswer=0;  
    9.   

    10. bool prime(int a)  

    11. {  

    1. 12.      for(int i=2;i<=sqrt(a);i++)  
    2. 13.        if (a%i==0) return false;  
    3. 14.      return true;  

    15. }  

    1. 16.   

    17. int generate(int i,int j)  

    18. {  

    1. 19.     if (j==1)  
    2. 20.     {  
    3. 21.         char a[30];  
    4. 22.         sprintf(a,"%d",i);  
    5. 23.         int len=strlen(a);  
    6. 24.         for(int k=0;k<len;k++)  
    7. 25.            a[k+len]=a[len-k-1];  
    8. 26.         a[len*2]='';  
    9. 27.         char* b;  
    10. 28.         return strtol(a,&b,10);  
    11. 29.     }  
    12. 30.     if (j==0)  
    13. 31.     {  
    14. 32.         char a[30];  
    15. 33.         sprintf(a,"%d",i);  
    16. 34.         int len=strlen(a);  
    17. 35.         for(int k=0;k<len;k++)  
    18. 36.            a[k+len-1]=a[len-k-1];  
    19. 37.         a[len*2-1]='';  
    20. 38.         char* b;  
    21. 39.         return strtol(a,&b,10);  
    22. 40.     }  

    41. }  

    1. 42.   

    43. int compareint(const void* a,const void* b)  

    44. {  

    1. 45.     return *((int *)a)-*((int *)b);  

    46. }  

    1. 47.   

    48. int main()  

    49. {  

    1. 50.   
    2. 51.     scanf("%d%d",&A,&B);  
    3. 52.   
    4. 53.     int x;  
    5. 54.     for(int i=1;i<=9999;i++)  
    6. 55.     for(int j=0;j<2;j++)//0:odd 1:even  
    7. 56.       if (prime(x=generate(i,j))&&x>=A&&x<=B)  
    8. 57.          answer[numAnswer++]=x;  
    9. 58.   
    10. 59.     qsort(answer,numAnswer,sizeof(int),compareint);  
    11. 60.   
    12. 61.     for(int i=0;i<numAnswer;i++)  
    13. 62.       printf("%d ",answer[i]);  
    14. 63.   
    15. 64.     return 0;  

    65. }  

     

     

    D.就这个计算

    题型:大数计算

    题意:

    大数(+/-)运算

    思路:

    以手算的方式模拟即可

    因为进位的关系,需要将数字倒置过来,进行运算。

    代码:/*代码来自42号参赛队伍*/

    [cpp] view plaincopy

    1. #include <stdio.h>  
    2. #include <stdlib.h>  
    3. #include <string.h>  
    4. #define M 1005  
    5. int main()  
    6. {  
    7.     char a[M],b[M];  
    8.     int c[M],d[M],e[M],f[M];  
    9.     int i,j,num;  
    10. 10.     while(scanf("%s",a)!=EOF&&scanf("%s",b)!=EOF)  
    11. 11.     {  
    12. 12.         j=0;  
    13. 13.         num=0;  
    14. 14.         memset(c,0,sizeof(c));  
    15. 15.         memset(e,0,sizeof(e));  
    16. 16.         memset(d,0,sizeof(d));  
    17. 17.         for(i=strlen(a)-1;i>=0;i--)  
    18. 18.         {  
    19. 19.             c[j++]=a[i]-'0';  
    20. 20.         }  
    21. 21.         j=0;  
    22. 22.         for(i=strlen(b)-1;i>=0;i--)  
    23. 23.         {  
    24. 24.             d[j++]=b[i]-'0';  
    25. 25.         }  
    26. 26.         for(i=0;i<strlen(a);i++)  
    27. 27.         {  
    28. 28.             e[i]+=c[i]+d[i];  
    29. 29.             if(e[i]>=10)  
    30. 30.             {  
    31. 31.                 e[i]-=10;  
    32. 32.                 e[i+1]+=1;  
    33. 33.             }  
    34. 34.             else  
    35. 35.             {  
    36. 36.                 continue;  
    37. 37.             }  
    38. 38.         }  
    39. 39.         num=strlen(a)-1;  
    40. 40.         if(e[strlen(a)]>0)  
    41. 41.             num=num+1;  
    42. 42.         i=num;  
    43. 43.         while(e[i]==0) i--;  
    44. 44.         if(i<0) printf("0");  
    45. 45.         else  
    46. 46.         {  
    47. 47.         for(;i>=0;i--)  
    48. 48.         {  
    49. 49.             printf("%d",e[i]);  
    50. 50.         }  
    51. 51.         }  
    52. 52.         printf(" ");  
    53. 53.         memset(e,0,sizeof(e));  
    54. 54.         for(i=0;i<strlen(a);i++)  
    55. 55.         {  
    56. 56.             e[i]+=c[i]-d[i];  
    57. 57.             if(e[i]<0)  
    58. 58.             {  
    59. 59.                 e[i]+=10;  
    60. 60.                 e[i+1]--;  
    61. 61.             }  
    62. 62.         }  
    63. 63.         num=strlen(a);  
    64. 64.         i=num-1;  
    65. 65.         while(e[i]==0) i--;  
    66. 66.         if(i<0) printf("0");  
    67. 67.         for(;i>=0;i--)  
    68. 68.             printf("%d",e[i]);  
    69. 69.         printf(" ");  

    70. }  

    71. return 0;  

    72. }  

    E.矩形覆盖

    题型:模拟

    题意:

    一个8*8的矩阵,该矩阵每个位置上的值都为非负数,且小于等于255。在处理这个矩阵时,需要提取一个特征矩阵,用这个矩阵覆盖原8*8矩阵中所有的非零的点.

     

    思路:

    有多种方法

    1.获得所有非零点,然后进行多次排序(分别获得x,y的最大值和最小值)

    2.无须知道具体的点,只需要对应的边界。即我们只需要知道特征矩阵的第一行和最后一行,第一列与最后一列。

    代码:/*代码来自Assassin*/

    [cpp] view plaincopy

    1. /*排序版本*/  
    2. #include <iostream>  
    3. #include <cstdio>  
    4. #include <algorithm>  
    5. #include <vector>  
    6. using namespace std;  
    7. typedef struct{  
    8.     int x;  
    9.     int y;  

    10. }POINT;  

    11. vector<POINT> v;  

    12. int sortX(const POINT &a, const POINT &b){  

    1. 13.     return a.x < b.x;  

    14. }  

    15. int sortY(const POINT &a, const POINT &b){  

    1. 16.     return a.y < b.y;  

    17. }  

    18. int main()  

    19. {  

    1. 20.     POINT p;  
    2. 21.     int data;  
    3. 22.     for(int i = 1; i <= 8; ++i){  
    4. 23.         for(int j = 1; j <= 8; ++j){  
    5. 24.             cin >> data;  
    6. 25.             if(data){  
    7. 26.                 p.x = i;  
    8. 27.                 p.y = j;  
    9. 28.                 v.push_back(p);  
    10. 29.             }  
    11. 30.         }  
    12. 31.     }  
    13. 32.     int x1, x2, y1, y2;  
    14. 33.     sort(v.begin(), v.end(), sortX);  
    15. 34.     x1 = v[0].x, x2 = v[v.size()-1].x;  
    16. 35.     sort(v.begin(), v.end(), sortY);  
    17. 36.     y1 = v[0].y, y2 = v[v.size()-1].y;  
    18. 37.     printf("%d %d %d %d ", x1, y1, x2, y2);  
    19. 38.     return 0;  

    39. }  

    [cpp] view plaincopy

    1. /*模拟版本*/  
    2. #include <iostream>  
    3. #include <cstdio>  
    4. #include <algorithm>  
    5. #include <cstring>  
    6. using namespace std;  
    7. int main()  
    8. {  
    9.     int data[9][9];  
    10. 10.     int row[9];  
    11. 11.     int col[9];  
    12. 12.     int x1, y1, x2, y2;  
    13. 13.     memset(data, 0, sizeof(data));  
    14. 14.     memset(row, 0, sizeof(row));  
    15. 15.     memset(col, 0, sizeof(col));  
    16. 16.     for(int i = 1; i <= 8; ++i){  
    17. 17.         for(int j = 1; j <= 8; ++j){  
    18. 18.             cin >> data[i][j];  
    19. 19.             row[i] += data[i][j];  
    20. 20.             col[j] += data[i][j];  
    21. 21.         }  
    22. 22.     }  
    23. 23.     for(int i = 1; i <= 8; ++i){  
    24. 24.         if(row[i] != 0){  
    25. 25.             x1 = i;  
    26. 26.             break;  
    27. 27.         }  
    28. 28.     }  
    29. 29.     for(int i = 8; i >= 1; --i){  
    30. 30.         if(row[i] != 0){  
    31. 31.             x2 = i;  
    32. 32.             break;  
    33. 33.         }  
    34. 34.     }  
    35. 35.     for(int i = 1; i <= 8; ++i){  
    36. 36.         if(col[i] != 0){  
    37. 37.             y1 = i;  
    38. 38.             break;  
    39. 39.         }  
    40. 40.     }  
    41. 41.     for(int i = 8; i >= 1; --i){  
    42. 42.         if(col[i] != 0){  
    43. 43.             y2 = i;  
    44. 44.             break;  
    45. 45.         }  
    46. 46.     }  
    47. 47.     printf("%d %d %d %d ", x1, y1, x2, y2);  
    48. 48.     return 0;  

    49. }  

     

    F. 铁轨问题

    题型:数据结构

    题意:

    每辆火车都从A方向驶入车站,再从B方向驶出车站,同时它的车厢可以进行某种形式的重新组合。假设从A方向驶来的火车有n节车厢(n<1000),分别按顺序编号为1,2,...,n。假定在进入车站之前每节车厢之间都是不连着的,并且它们可以自行移动,直到处在B方向的铁轨上。另外假定车站C里可以停放任意多节的车厢。但是一旦当一节车厢进入车站C,它就不能再回到A方向的铁轨上了,并且一旦当它进入B方向的铁轨后,它就不能再回到车站C。负责车厢调度的工作人员需要知道能否使它以a1,a2,...,an的顺序从B方向驶出。
            请写一个程序,用来判断能否得到指定的车厢顺序。

     

    思路:

    用栈来模拟即可,用数组来实现栈。

     

    代码:/*代码来自42号参赛队伍*/

    [cpp] view plaincopy

    1. #include<stdio.h>  
    2.    
    3. #define MAXN 1010  
    4. int n,target[MAXN],m;  
    5.    
    6. int main()  
    7. {  
    8.    
    9.     while(scanf("%d%d",&m,&n)!=EOF)  
    10. 10.     {  
    11. 11.         int A=1,B=1;  
    12. 12.         int stack[MAXN],top=0;  
    13. 13.         for(int i=m;i<=n;i++)  
    14. 14.         {  
    15. 15.         scanf("%d",&target[i]);  
    16. 16.         }  
    17. 17.         int ok=1;  
    18. 18.         while(B<=n)  
    19. 19.         {  
    20. 20.             if(A==target[B]) {A++; B++;}  
    21. 21.             else if(top&&stack[top]==target[B]) {top--;B++;}  
    22. 22.             else if(A<=n) stack[++top]=A++;  
    23. 23.             else {ok=0; break;}  
    24. 24.         }  
    25. 25.         printf("%s ",ok ? "YES": "NO");  
    26. 26.     }  
    27. 27.     return 0;  

    28. }  

     

    G. 团队博弈

    题型:博弈问题

    题意:

    ACM团队的招新面试到了最后一轮,有两个能力相当的人(Alice & Bob),可是只有ACM团队只剩最后一个名额了。因此无奈下只能考验Alice & Bob的聪颖程度。现假设Alice & Bob都随身携带着无数个硬币,他们轮流向一个空箱子内投入硬币,投入的硬币数量一个是个正整数,并且每人每次投入不超过m个(1<=m<=10)。最先使空盒子内硬币的数量大于或者等于n(0<n<10000)的一方胜出。Alice & Bob都非常渴望加入ACM团队,而且都是非常聪明的人。假设Alice先手。

     

    思路:

    当n == K(m+1)  K为正整数

    每次Alice拿a个,Bob都可以拿(m+1-a)个,使剩余目标量为(K-1)(m+1)...直到最后Bob获胜

    当N != K(m+1) K为正整数

    Alice可以拿a个,使得 N == K(m+1), 使Bob进入上述困境

     

    代码:/*代码来自37号参赛队伍*/

    [cpp] view plaincopy

    1. #include<stdio.h>  
    2. int main()  
    3. {  
    4.     int n,m,s,i=1;  
    5.     scanf("%d",&s);  
    6.     while(i<=s){  
    7.         scanf("%d%d",&n,&m);  
    8.             if(n%(m+1)==0)  
    9.                 printf("Bob ");  
    10. 10.             else  
    11. 11.                 printf("Alice ");  
    12. 12.             i++;  
    13. 13.     }  
    14. 14.     return 0;  

    15. }  

     

     

    H. 五柳先生传

    题型:搜索,BFS

    题意:

     五柳先生"性嗜酒,家贫,不能常得,亲旧知其如此,或置酒而招之。"可是经考古发现,五柳先生是个处女座,有极度强迫症。他每次只喝一杯酒,且这杯酒里有且仅有一定体积的酒,他才会喜欢喝。
            五柳先生家有两个无刻度标志的酒壶,分别可装 x 升和 y 升 ( x,y 为整数且均不大于 100 )的酒。设另有一酒缸,可用来向酒壶灌酒或接从酒壶中倒出的酒, 两酒壶间,酒也可以相互倾倒。已知 x 升壶为空壶, y 升壶为空壶。问如何通过倒酒或灌酒操作, 用最少步数能在x或y升的壶中量出 z ( z ≤ 100 )升的酒来。

     

    思路:

    http://blog.csdn.net/neeeeew/article/details/19207181

    在本博客中的“简易搜索”博文内有详细提及,此题略去了输出步骤

    代码:/*代码来自Assassin*/

    [cpp] view plaincopy

    1. #include<iostream>  
    2. #include<cstring>  
    3. #define min(a, b) (a)>(b)?(b):(a)  
    4. using namespace std;  
    5. const int Max = 101;  
    6. struct node{  
    7.     int ope;  int a;  int b;  node* pre;  
    8. } que[Max * Max];  
    9. bool vis[Max][Max];  

    10. char str[6][10] = {"FILL(1)", "FILL(2)", "DROP(1)", "DROP(2)", "POUR(1,2)", "POUR(2,1)"};  

    11. void print(node now){  

    1. 12.     if (now.pre != NULL){  
    2. 13.         print(*now.pre);                /*这种输出路径的方法很值得学习*/  
    3. 14.         cout << str[now.ope] << endl;  
    4. 15.     }  

    16. }  

    17. void bfs(int a, int b, int c){  

    1. 18.     int steps = 0;  
    2. 19.     int head = 0, tail = 1;  
    3. 20.     que[0].a = que[0].b = 0;  
    4. 21.     que[0].pre = NULL;  
    5. 22.     while (tail - head > 0)     {  
    6. 23.         int count = tail - head;        /*head表示队列中的首元素*/  
    7. 24.                                         /*tail表示队列中的尾元素*/  
    8. 25.         while (count --){  
    9. 26.             node now = que[head];  
    10. 27.             if (now.a == c || now.b == c){  
    11. 28.                 cout << steps << endl;  
    12. 29.                 //print(now);  
    13. 30.                 return;  
    14. 31.             }  
    15. 32.             if (!vis[a][now.b]){        /*fill(1)*/  
    16. 33.                 que[tail].ope = 0;  
    17. 34.                 que[tail].a = a;  
    18. 35.                 que[tail].b = now.b;  
    19. 36.                 que[tail].pre = &que[head];  
    20. 37.                 vis[a][now.b] = true;  
    21. 38.                 tail++;  
    22. 39.             }  
    23. 40.             if (!vis[now.a][b]){        /*fill(2)*/  
    24. 41.                 que[tail].ope = 1;  
    25. 42.                 que[tail].a = now.a;  
    26. 43.                 que[tail].b = b;  
    27. 44.                 que[tail].pre = &que[head];  
    28. 45.                 vis[now.a][b] = true;  
    29. 46.                 tail++;  
    30. 47.             }  
    31. 48.             if (!vis[0][now.b]){     /*drop(1)*/  
    32. 49.                 que[tail].ope = 2;  
    33. 50.                 que[tail].a = 0;  
    34. 51.                 que[tail].b = now.b;  
    35. 52.                 que[tail].pre = &que[head];  
    36. 53.                 vis[0][now.b] = true;  
    37. 54.                 tail ++;  
    38. 55.             }  
    39. 56.             if (!vis[now.a][0]){        /*drop(2)*/  
    40. 57.                 que[tail].ope = 3;  
    41. 58.                 que[tail].a = now.a;  
    42. 59.                 que[tail].b = 0;  
    43. 60.                 que[tail].pre = &que[head];  
    44. 61.                 vis[now.a][0] = true;  
    45. 62.                 tail ++;  
    46. 63.             }  
    47. 64.             int wat1 = min(now.a, b - now.b);  
    48. 65.             if (!vis[now.a - wat1][now.b + wat1]){  /*pour(1,2)*/  
    49. 66.                 que[tail].ope = 4;  
    50. 67.                 que[tail].a = now.a - wat1;  
    51. 68.                 que[tail].b = now.b + wat1;  
    52. 69.                 que[tail].pre = &que[head];  
    53. 70.                 vis[now.a - wat1][now.b + wat1] = true;  
    54. 71.                 tail ++;  
    55. 72.             }  
    56. 73.             int wat2 = min(a - now.a, now.b);  
    57. 74.             if (!vis[now.a + wat2][now.b - wat2]){      /*pour(2,1)*/  
    58. 75.                 que[tail].ope = 5;  
    59. 76.                 que[tail].a = now.a + wat2;  
    60. 77.                 que[tail].b = now.b - wat2;  
    61. 78.                 que[tail].pre = &que[head];  
    62. 79.                 vis[now.a + wat2][now.b - wat2] = true;  
    63. 80.                 tail ++;  
    64. 81.             }  
    65. 82.             head ++;  
    66. 83.         }  
    67. 84.         steps ++;  
    68. 85.     }  
    69. 86.     cout << "impossible" << endl;  

    87. }  

    1. 88.   

    89. int main()  

    90. {  

    1. 91.     int a, b, c;  
    2. 92.     cin >> a >> b >> c;  
    3. 93.     memset(vis, falsesizeof(vis));  
    4. 94.     vis[0][0] = true;  
    5. 95.     bfs(a, b, c);  
    6. 96.     return 0;  

    97. }  

     

    I进击的海怪

    题型:搜索,DFS, FLOOD FILL

    题意:

    WA海怪是一种独居的海怪,具有很强的进攻性,因此在一块连通域(上下、左右连通)内有且仅有一只WA海怪。现在我们想知道这片AC海洋中有多少只WA海怪。

     

    思路:

    http://blog.csdn.net/neeeeew/article/details/19207181

    在本博客中的“简易搜索”博文内有详细提及

    代码:/*代码来自56号参赛队伍*/

    [cpp] view plaincopy

    1. #include <iostream>  
    2. #include <cstdio>  
    3. #include <cstdlib>  
    4. #include <cstring>  
    5. using namespace std;  
    6. #define MIN(x,y) (x<y?x:y)  
    7. #define MAX(x,y) (x>y?x:y)  
    8.   
    9. char map[1010][1010];  

    10. bool visit[1010][1010];  

    11. int ans = 0;  

    12. int tx[] = {0,1,0,-1};  

    13. int ty[] = {1,0,-1,0};  

    14. int m,n;  

    1. 15.   

    16. void dfs(int x, int y){  

    1. 17.     if(x<0||x>=m||y<0||y>=n)  
    2. 18.         return;  
    3. 19.     visit[x][y] = true;  
    4. 20.     map[x][y] = '.';  
    5. 21.     for(int i=0; i<4; ++i){  
    6. 22.         int tmpx = x+tx[i];  
    7. 23.         int tmpy = y+ty[i];  
    8. 24.         if(!visit[tmpx][tmpy]&&map[tmpx][tmpy]=='#')  
    9. 25.             dfs(tmpx, tmpy);  
    10. 26.     }  

    27. }  

    1. 28.   

    29. int main(){  

    1. 30.     scanf("%d%d",&m,&n);  
    2. 31.     int i,j;  
    3. 32.     for(i=0; i<m; ++i){  
    4. 33.         scanf("%s", map[i]);  
    5. 34.     }  
    6. 35.     memset(visit, falsesizeof(visit));  
    7. 36.     for(i=0; i<m; ++i){  
    8. 37.         for(j=0; j<n; ++j){  
    9. 38.             if(map[i][j] != '.'){  
    10. 39.                 ++ans;  
    11. 40.                 dfs(i,j);  
    12. 41.             }  
    13. 42.         }  
    14. 43.     }  
    15. 44.     printf("%d ", ans);  
    16. 45.     return 0;  

    46. }  

     

    J最大合成数

    题型:贪心

    题意:

      ACM团队里有这么一群人,茶余饭后,总能想出一些奇怪的游戏。刚刚考完数据结构的石头突然想到一个游戏:他随机给出n个整数,让Hacker将这组整数串成一个多位数。请问,最大的多位数是多少? 。

     

    思路:

    首先很常见的就是对字符串进行排序。然后就来了一个很大的漏洞 20 2。如果按照排序合成的202,可是我们可以很明显的看出来220更大。因此,当两个数字其中为其一个数字的前缀时,我们可以对这两个数进行拼接,查看那种拼接方式能获得更大解。

    代码:/*代码来自Assassin*/

    [cpp] view plaincopy

    1. #include <iostream>  
    2. #include <cstring>  
    3. #include <cstdio>  
    4. #include <algorithm>  
    5. using namespace std;  
    6. typedef struct{  
    7.     char str[1000];  
    8. }NUM;  
    9. NUM number[25];  

    10. int cmp(const NUM &a, const NUM &b){  

    11. //    return strcmp(a.str, b.str) < 0;  

    12. //    printf("%s %s %d ", a.str, b.str, strcmp(a.str, b.str));  

    1. 13.     char stra[1000], strb[1000];  
    2. 14.     strcpy(stra, a.str);  
    3. 15.     strcpy(strb, b.str);  
    4. 16.     bool flag = true;  
    5. 17.     for(int i = 0; i < strlen(a.str) && i < strlen(b.str); ++i){  
    6. 18.         if(a.str[i] != b.str[i]){  
    7. 19.             flag = false;  
    8. 20.             break;  
    9. 21.         }  
    10. 22.     }  
    11. 23.     if(!flag){  
    12. 24.         return strcmp(a.str, b.str) < 0;  
    13. 25.     }  
    14. 26.     else{  
    15. 27.         return strcmp(strcat(stra, strb), strcat(strb, stra)) < 0;  
    16. 28.     }  

    29. }  

    30. int main(){  

    1. 31.     int cas;  
    2. 32.     cin >> cas;  
    3. 33.     for(int i = 0; i < cas; ++i){  
    4. 34.         scanf("%s", number[i].str);  
    5. 35.     }  
    6. 36.     sort(number, number+cas, cmp);  
    7. 37.     for(int i = cas-1; i >= 0; --i){  
    8. 38.         printf("%s", number[i].str);  
    9. 39.     }  
    10. 40.     printf(" ");  
    11. 41.     return 0;  

    42. }  

  • 相关阅读:
    富士康前端一面
    中孚前端面筋
    至真科技校招前端面筋
    SysFader:iexplore.exe错误
    设置文件属性
    SQL2000数据库定期自动备份与修改
    如何配置jdk1.5的环境变量及运行java程序
    ResultSet的getDate()、getTime()和getTimestamp()比较
    Java BigDecimal详解
    MVVM教程(一):MVVM简介与准备工作
  • 原文地址:https://www.cnblogs.com/ghostTao/p/3716558.html
Copyright © 2020-2023  润新知