zoukankan      html  css  js  c++  java
  • 解题报告

    1、Xxy 的车厢调度
    (train.cpp/c/pas)
    Description
                                                                                                                                                                                                        ,   


    再从 B 方向驶出,同时它的车厢可以重新组合。假设
    从 A 方向驶来的火车有 n 节(n<=1000) ,分别按照顺
    序编号为 1,2,3,…,n。假定在进入车站前,每节
    车厢之间都不是连着的,并且它们可以自行移动到 B
    处的铁轨上。 另外假定车站 C 可以停放任意多节车厢。
    但是一旦进入车站 C,它就不能再回到 A 方向的铁轨
    上了,并且一旦当它进入 B 方向的铁轨,它就不能再
    回到车站 C。
    负责车厢调度的 xxy 需要知道能否使它以
    a1,a2,…,an 的顺序从 B 方向驶出,请来判断能否得到
    指定的车厢顺序。
    Input
    输入文件的第一行为一个整数 n,其中 n<=1000,表示有 n 节车厢,第二行为 n 个数字,表
    示指定的车厢顺序。
    Output
    如果可以得到指定的车厢顺序,则输出一个字符串”YES”,否则输出”NO”(注意要大写,不
    包含引号) 。还有,xxy 说了 这题 AC 有糖吃。
    Example
    train.in train.out
    5
    5 4 3 2 1
    YES
    Hint
    对于 50%的数据,1<=N<=20。
    对于 100%的数据,1<=N<=1000。

    【思路】

    模拟法做 B相当于是一个栈

    如果站内没有当前行驶来的车,则将小于当前车的编号的车全部入栈(包括当前车)

    再将这辆车驶出;若当前车在栈中直接将它驶出。否则无解。

    (注意输出大小写。。。吃亏了。。。)

    【代码】

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 using namespace std;
     5 const int maxx=1001;
     6 int a[maxx];
     7 int stack[maxx];
     8 int main()
     9 {
    10 //    freopen("train.in","r",stdin);
    11 //    freopen("train.out","w",stdout);
    12     int n;
    13     scanf("%d",&n);
    14     for(int i=1;i<=n;i++)
    15     scanf("%d",&a[i]);
    16     int cur=1;
    17     int top=0;
    18     for(int i=1;i<=n;i++)
    19     {
    20         while(cur<=a[i])
    21         stack[++top]=cur++;
    22         if(stack[top]==a[i])
    23         --top;
    24         else
    25         {
    26                 printf("NO");
    27                 return 0;
    28         }
    29     
    30     }
    31     printf("YES");
    32 //    fclose(sdtin);
    33 //    fclose(stdout);
    34     return 0;
    35 }
    View Code

    2、迷 宫

    (maze.cpp/c/pas)
    Description
    Karles 和朋友到迷宫玩耍,没想到遇上了 10000000 年一次的大洪水,好在 Karles 是一个喜
    欢思考的人,他发现迷宫的地形和洪水有如下性质:
    ①迷宫可以被看做是一个 N*M 的矩形方阵,其中左上角坐标为(1,1),右下角坐标为(n,m),
    每个格子(i,j)都有一个高度 h(i,j)。
    ②洪水从(sx,sy)开始,如果一个格子被洪水淹没,那这个格子四周比它低(或相同)的格子
    也会被淹没。
    现在 Karles 想请你帮忙算算,有多少个格子不会被淹没,以及 Karles 想问一下格子(x,y)是否
    被淹没,如果被淹没的话就输出”Yes”,否则输出”No”。
    Input
    第一行包含两个整数 n,m。
    以下 n 行,每行 m 个数,第 i 行第 j 个数表示格子高度 h(i,j)。
    下面一行包含两个整数 sx,sy,表示最初被洪水淹没的格子。
    下面一行包含一个整数 q,表示询问的数量。
    最后 q 行每行包含两个整数 x,y,表示询问的格子。
    Output
    输出的第一行,为永远不会被淹没的格子的数量。
    以下 q 行,为格子被淹没的情况,输出”Yes”或者”No”(不包含引号)
    Example
    maze.in maze.out
    3 3
    1 2 3
    2 3 4
    3 4 5
    2 2
    2
    1 2
    2 3
    5
    Yes
    No
    Hint
    对于 10%的数据,(sx,sy)为迷宫内的最高点。
    对于 30%的数据,1<=N,M<=5,q=1。
    对于 60%的数据,1<=N,M<=100,q<=100。
    对于 100%的数据,1<=N,M<=2000,q<=1000。

    【思路】广搜 相当于细胞搜索;

    从被洪水淹没的格子开始搜素(方向为上下左右),如果海拔小于等于当前格子则入队,并做好标记表示已经被淹了,

    入队的条件为 没有出界,海拔小于等于当前搜索的海拔 并且没有被淹(即还没有做标记)!!!(经常忘记)

    直到队列元素为空 ,全部都扫一遍,没有打标记的就是没有淹的;

    (还是要注意输出大小写。。。)

    【代码】

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 using namespace std;
     5 const int maxx=2001;
     6 int mmap[maxx][maxx];
     7 int dx[4]={0,1,-1,0},
     8     dy[4]={1,0,0,-1};
     9 bool vis[maxx][maxx];
    10 int qque[maxx][maxx];
    11 int n,m;
    12 void bfs(int x,int y)
    13 {
    14     vis[x][y]=1;
    15     int head=0,t=1;
    16     qque[1][1]=x;
    17     qque[1][2]=y;
    18     do
    19     {
    20         head++;
    21         for(int i=0;i<=3;i++)
    22         {
    23             int xx=qque[head][1]+dx[i];
    24             int yy=qque[head][2]+dy[i];
    25             if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&mmap[xx][yy]<=mmap[qque[head][1]][qque[head][2]]&&!vis[xx][yy])
    26             {
    27                 vis[xx][yy]=1;
    28                 t++;
    29                 qque[t][1]=xx;
    30                 qque[t][2]=yy;
    31             }
    32         }
    33     }while(head<=t);
    34 }
    35 int main()
    36 {
    37     //freopen("maze.in","r",stdin);
    38     //freopen("maze.out","w",stdout);
    39     scanf("%d%d",&n,&m);
    40     for(int i=1;i<=n;i++)
    41     for(int j=1;j<=m;j++)
    42     scanf("%d",&mmap[i][j]);
    43     int x,y;
    44     scanf("%d%d",&x,&y);
    45    bfs(x,y);
    46     int sum=0;
    47     for(int i=1;i<=n;i++)
    48     for(int j=1;j<=m;j++)
    49     {
    50         if(!vis[i][j])
    51         sum++;
    52     }
    53     printf("%d
    ",sum);
    54     int t;
    55     scanf("%d",&t);
    56     int i,j;
    57     while(t--)
    58     {
    59         scanf("%d%d",&i,&j);
    60         if(vis[i][j])
    61         printf("No
    ");
    62         else
    63         printf("Yes
    ");
    64     }
    65 //    fclose(stdin);
    66 //    fclose(stdout);
    67     return 0;
    68 }
    View Code

    3.发 零 食

    (dropping.cpp/c/pas)
    Description
    HKD 看学弟学妹们学习辛苦,决定给发零食吃
    HKD 是土豪,所以他决定买零食的时候,从 1 块钱的开始买,然后买 2 块钱的,然后 3 块钱
    的,……,直至 D 块钱的。而且 k 块钱的零食买 2^(k-1)个。
    但 HKD 从来不吃零食,所以他不知道他买的零食是否好吃。
    于是他把所有零食编号,怎么编呢?
    对于价钱为 k 的零食,从 1 开始编,然后 2,3,编到 2^(k-1)
    例:1 块钱的:1
    2 块钱的:1 2
    3 块钱的:1 2 3 4
    学编程的基本功是搜索嘛
    为了考验学弟学妹们的搜索能力
    HKD 把所有零食掺杂在了一起,送到学弟学妹们的面前(送货上门,真好)
    他规定:
    1、只能排队一个一个开始搜
    2、所有人最终只能吃 1 个零食
    3、所有人只能吃最贵的零食
    4、 所有人搜索零食的时候, 只能从 1 块钱的开始搜, 然后搜 2 块钱的, 然后搜 3 块钱的……,
    直到最贵的
    5、初始时认为所有零食都是好吃的
    6、 为了增加难度, HKD 制定了新规定: 若一个人搜到的第 i 块钱的编号为 j 的零食是好吃的,
    那么他就把这个零食更改为不好吃,然后去搜第 i+1 块钱的编号为 j*2-1 的零食。若一个人
    搜到的第 i 块钱的编号为 j 的零食是不好吃的,那么他就把这个零食更改为好吃,然后去搜
    第 i+1 块钱的编号为 j*2 的零食
    注:若 n 个人都最后搜到了同一个零食,那么他们就分享一个吧
    然而不知道为啥,HKD 想知道最后一个人吃的是编号为几的零食
    那就麻烦最后一个人告诉他吧
    注:若其中有一个人无法搜到最贵的零食,就告诉他-1
    Input
    第一行输入测试点编号
    下一行输入 T,表示有 T 组数据
    接下来 T 行,每行输入 2 个数输入 D 和学弟学妹的人数 M
    Output
    对于每组测试数据
    输出一行 k : ans,表示第 k 组数据的答案为 ans
    冒号与每个数字之间空 1 格
    每 2 组数据之间空一行
    Example
    dropping.in dropping.out
    1
    6
    4 2
    3 4
    10 1
    2 2
    8 128
    1 : 12
    2 : 7
    3 : 512
    4 : 3
    5 : 255
    Hint
    测试点编号
    T D
    1、2
    <=1 <=10
    3、4、5
    <=20 <=25
    6、7、8、9
    <=700 <=30
    10 <=1 <=1
    学弟学妹人数 M <2^31 且不超过 D 块钱的零食个数。

    【思路】:由题目描述可知,这是一棵完全二叉树;

    每一层为 2的层次方-1;从第一层的第一个结点开始,到每一个结点的条件是好吃与不好吃;

    最后一定会出界,出界时跳出;将刚出界点的编号/2,就是出界之前的点;即为最贵的零食;

    :结点k的左右子结点的标号为2*看,2*k+1;

    之前没想到是因为不理解题意;而且没有敏感的认识到2^k-1为完全二叉树每层的结点数

    状态改变 循环+取反 边界:为出界即超过最贵的零食的那一层;

    学到的  1<<Max     为2^max‘

    【代码】

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxx=20;
     6 int s[1<<maxx];//为2的maxx次方,因为最大结点数为2的maxx-1; 
     7 int main()
     8 {
     9     int n,k=1;
    10     scanf("%d",&n);//测试点 
    11     int t;
    12     scanf("%d",&t);//t组测试数据 
    13     while(t--)
    14     {
    15         int d,I;//钱和同学 
    16         scanf("%d%d",&d,&I);
    17         int n=(1<<d)-1;//n为最大结点的标号 
    18         memset(s,0,sizeof(s));//好吃与不好吃 
    19         for(int i=0;i<I;i++)//从第一个同学开始搜 
    20         {
    21              k=1;//从1块钱开始搜 
    22             for(;;)
    23             {
    24                 s[k]=!s[k];//状态变成相反 
    25                 k=s[k]?k*2:k*2+1;//去哪个零食 
    26                 if(k>n)break;//已经出界了跳出 
    27             }
    28         }
    29         printf("%d
    ",k/2);//出界之后/2就是这个结点的爸爸 
    30     }
    31     return 0;
    32 }
    View Code
  • 相关阅读:
    LeetCode "Super Ugly Number" !
    LeetCode "Count of Smaller Number After Self"
    LeetCode "Binary Tree Vertical Order"
    LeetCode "Sparse Matrix Multiplication"
    LeetCode "Minimum Height Tree" !!
    HackerRank "The Indian Job"
    HackerRank "Poisonous Plants"
    HackerRank "Kundu and Tree" !!
    LeetCode "Best Time to Buy and Sell Stock with Cooldown" !
    HackerRank "AND xor OR"
  • 原文地址:https://www.cnblogs.com/zzyh/p/6679990.html
Copyright © 2011-2022 走看看