• 【题目自解】北京大学2016计算机学科夏令营上机考试


    【题目自解】北京大学2016计算机学科夏令营上机考试

    A:分段函数(NOI 1.4编程基础之逻辑表达式与条件分支)

    解题思路

    这题就像逗我玩似的,这连简单题都算不上。

    AC代码

    #include<cstdio>
    
    using namespace std;
    
    int main()
    {
        double x, y;
        scanf("%lf", &x);
        if (x >= 0 && x < 5)y = 2.5 - x;
        else if (x >= 5 && x < 10)y = 2 - 1.5*(x - 3)*(x - 3);
        else if (x >= 10 && x < 20)y = x / 2 - 1.5;
        printf("%.3lf", y);
        return 0;
    }

    B:单词翻转(NOI 1.7编程基础之字符串)

    解题思路

    简单题,读取一整行用C的gets()函数,VS2017没有这个函数,Dev和OJ可以过。

    AC代码

    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    int main()
    {
        char s[505];
        gets(s);
        int len = strlen(s);
        for (int i = 0; i < len; i++)
        {
            if (s[i] == ' ')printf(" ");
            if (s[i] == '_')continue;
            else
            {
                int wlen = 0;
                int tmp = i;
                while (s[tmp] != ' ')
                {
                    wlen++; tmp++;
                    if (tmp >= len) break;
                }
                for (int j = i + wlen - 1; j >= i; j--)
                {
                    printf("%c", s[j]);
                    s[j] = '_';
                }
            }
        }
        return 0;
    }

    C:反反复复(NOI  1.8编程基础之多维数组)

    解题思路

    简单题,最基础的二维数组。

    AC代码

    #include<cstdio>
    #include<cstring>
    int N[205][205];
    
    int main()
    {
        int m, n;//列和行 
        char s[205];
        scanf("%d", &m);
        scanf("%s", s);
        int len = strlen(s);
        n = len / m;
        int cnt = 1;
        for (int i = 0; i < n; i++)//按行读入 
        {
            if (cnt % 2)//奇数行正向读入
            {
                for (int j = 0; j < m; j++)N[i][j] = s[i*m + j];
                cnt++;
            }
            else//偶数行反向读入
            {
                for (int j = m - 1; j >= 0; j--)N[i][m - 1 - j] = s[i*m + j];
                cnt++;
            }
        }
        for (int j = 0; j < m; j++)//按列输出 
        {
            for (int i = 0; i < n; i++)printf("%c", N[i][j]);
        }
        return 0;
    }

    G:重建二叉树

    解题思路

    详细讲解见二叉树专题。核心思想其实很简单,用数组就可以直接做,无非就是根据前序遍历的结果对中序遍历左右子串分别递归,最后后序打印根节点的值。

    AC代码

    #include<cstdio>
    #include<cstring>
    char s1[10000];//存储前序
    char s2[10000];//存储中序
    
    void f(int l, int l2, int r2)//总是需要前序遍历的起点和中序遍历的两端,以确定根结点和左右子树
    {
        if (l2 == r2)return;//没有元素了
        char r = s1[l];//根结点
        int loc = l2;
        while (s2[loc] != r)loc++;//找到根结点在中序遍历中的位置
        f(l + 1, l2, loc);
        f(l + loc + 1 - l2, loc + 1, r2);//画一画情况就知道了
        printf("%c", r);
    }
    
    int main()
    {
        while (scanf("%s%s", s1, s2) != EOF)
        {
            int len = strlen(s1);
            f(0, 0, len);
            printf("
    ");
        }
        return 0;
    }

    H:丛林中的路

    解题思路

    中等题,最小生成树的模板题。

    AC代码

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N = 30;
    int p[N];//父结点,A代表编号0
    int n, ans;//村落数目,最小开销
    
    struct Edge
    {
        int a, b;
        int cost;
    }edge[80];
    
    bool cmp(Edge a, Edge b)
    {
        return a.cost < b.cost;
    }
    
    void init()
    {
        for (int i = 0; i < n; i++)p[i] = i;
        ans = 0;
    }
    
    int find(int x)
    {
        return x == p[x] ? x : p[x] = find(p[x]);
    }
    
    void Union(int i)
    {
        int a = find(edge[i].a);
        int b = find(edge[i].b);
        if (a == b)return;
        else
        {
            p[b] = a;
            ans += edge[i].cost;
        }
    }
    
    int main()
    {
        int k, c, cnt;//与当前结点相连的村落数,和道路开销,以及总道路数目
        char a[5], b[5];//两结点名称
        while (scanf("%d", &n) != EOF && n != 0)
        {
            cnt = 0;
            for (int i = 0; i < n - 1; i++)
            {
                scanf("%s%d", a, &k);
                for (int j = 0; j < k; j++)
                {
                    scanf("%s%d", b, &c);
                    edge[cnt].cost = c;
                    edge[cnt].a = a[0] - 'A';
                    edge[cnt].b = b[0] - 'A';
                    cnt++;
                }
            }
            sort(edge, edge + cnt, cmp);
            init();
            for (int i = 0; i < cnt; i++) Union(i);
            printf("%d
    ", ans);
        }
        return 0;
    }

    F:Dungeon Master

    解题思路

    三维地图广搜,算是广搜的模板题了。写出来就AC了,没有什么注意点。

    AC代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    int l, r, c;
    char a[31][31][31];//存储地图
    int vis[31][31][31];//访问标记
    int dx[6] = { 0,0,1,-1,0,0 };
    int dy[6] = { 1,-1,0,0,0,0 };
    int dz[6] = { 0,0,0,0,1,-1 };
    
    struct Node
    {
        int z, x, y;//坐标
        int t;//计时
        Node() :z(-1), x(-1), y(-1),t(0){}
        Node(int zz, int xx,int yy):z(zz), x(xx),y(yy),t(0){}
    };
    
    Node s, e;//起点和终点
    
    bool noWay(int z,int x, int y)
    {
        if (z < 0 || z >= l || x < 0 || x >= r || y < 0 || y >= c)return true;
        if (vis[z][x][y])return true;
        if (a[z][x][y] == '#')return true;
        return false;
    }
    
    void bfs()
    {
        queue<Node> q;
        memset(vis, 0, sizeof(vis));
        q.push(s);//起点入队
        vis[s.z][s.x][s.y] = 1;
        while (!q.empty())//开始广搜
        {
            Node cur = q.front();
            if (cur.x == e.x&&cur.y == e.y&&cur.z == e.z)
            {
                printf("Escaped in %d minute(s).
    ", cur.t);
                return;
            }
            q.pop();
            for (int i = 0; i < 6; i++)
            {
                int nz = cur.z + dz[i];
                int nx = cur.x + dx[i];
                int ny = cur.y + dy[i];
                if (noWay(nz, nx, ny))continue;
                Node next(nz, nx, ny);
                vis[nz][nx][ny] = 1;
                next.t = cur.t + 1;
                q.push(next);//入队
            }
        }
        printf("Trapped!
    ");
    }
    
    int main()
    {
        while (scanf("%d%d%d", &l, &r, &c) != EOF && !(l == 0 && r == 0 && c == 0))
        {
            for (int k = 0; k < l; k++)
            {
                getchar();
                for (int i = 0; i < r; i++)
                {
                    for (int j = 0; j < c; j++)
                    {
                        scanf("%c", &a[k][i][j]);
                        if (a[k][i][j] == 'S')
                        {
                            s.z = k; s.x = i; s.y = j;
                        }
                        if (a[k][i][j] == 'E')
                        {
                            e.z = k; e.x = i; e.y = j;
                        }
                    }
                    getchar();//换行符
                }
            }
            bfs();
        }
        return 0;
    }

    D:文件结构“图”

    解题思路

    之前的一道程设作业题,确实挺麻烦的,自己第一次做就WA了,大佬AC代码如下。

    AC代码

    #define TAB "|     "
    
    #include<stdio.h>
    #include<string.h>
    #include<string> 
    #include<algorithm>
    
    using namespace std;
    
    int cases=1;
    char str[35];
    bool isFinish=false;
    
    void deal(int tab_num)
    {
        string file_name[35];
        int file_num=0;
        scanf("%s",str);
        if (tab_num==0 && str[0]!='#')
        {
            if (cases>1)
                printf("
    ");
            printf("DATA SET %d:
    ",cases);
            printf("ROOT
    ");
        }
        while (true)
        {
            if (str[0]=='*' || str[0]==']')
                break;
            else if (str[0]=='#')
            {
                isFinish=true;
                return;
            }
            else if (str[0]=='f')
                file_name[file_num++]=str;
            else if (str[0]=='d')
            {
                for (int i=0;i<tab_num+1;i++)
                    printf("%s",TAB);
                printf("%s
    ",str);
                deal(tab_num+1); 
            }
            scanf("%s",str);
        }
        sort(file_name,file_name+file_num);
        for (int i=0;i<file_num;i++)
        {   
            for (int j=0;j<tab_num;j++)
                printf("%s",TAB);
            printf("%s
    ",file_name[i].c_str());
        }
        return;
    }
    
    int main()
    {
        //freopen("output.txt","w",stdout);
        while (!isFinish)
        {
            deal(0);
            cases++;
        }
        return 0;
    }
  • 相关阅读:
    第五篇:常用模块
    第三篇:函数
    第七篇:面向对象高级
    第二篇:流程控制、数据类型、字符编码、文件处理
    第一篇:python入门
    Python-计算机硬件基础
    PYTHON-UDP
    PYTHON-TCP 粘包
    PYTHON-网络通信 TCP
    English Voice of <<Something just like this>>
  • 原文地址:https://www.cnblogs.com/yun-an/p/11111865.html
Copyright © 2020-2023  润新知