zoukankan      html  css  js  c++  java
  • 【题目自解】北京大学2017计算机学科夏令营上机考试

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

    A:判决素数个数 (NOI 1.13编程基础之综合应用)

    解题思路

    两个坑,一个是x,y大小关系不确定,要写一个交换;一个是取值范围可以到100000,因此i*i到了十位数量级,在int表示中是负数(虽然我觉得没到int限制范围啊,但是测试结果确实是这样),这时候访问数组会报错。

    如果继续用i*i,语句应该改为

    for (int j = i * i; j <= N && j>0; j += i) mark[j] = 1;

    AC代码(2*i版本)

    #include<cstdio>
    #include<cstring>
    const int N = 100000;
    int mark[N + 5] = { 0 };
    int num = 0;
    
    void Prime()
    {
        mark[1] = 1;
        for (int i = 2; i <= N; i++)
        {
            if (mark[i] == 1)continue;
            for (int j = 2 * i; j <= N; j += i) mark[j] = 1;
        }
    }
    
    int main()
    {
        int x, y;
        scanf("%d%d", &x, &y);
        if (x > y)
        {
            int t = y;
            y = x;
            x = t;
        }
        Prime();
        for (int i = x; i <= y; i++)
        {
            if (mark[i] == 0)num++;
        }
        printf("%d", num);
        return 0;
    }

    B:编码字符串

    解题思路

    简单题,直接做就行了。tolower的头文件是cctype,string里面也有。更简单的做法是边判断边输出。

    解题代码

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    char s[1005];
    char c[1005];//存储字符
    int n[1005];//存储每个字符的数量
    int cnt = 0;//分割段数-1
    
    int main()
    {
        scanf("%s", s);
        int len = strlen(s);
        for (int i = 0; i < len; i++)s[i] = tolower(s[i]);
        c[0] = s[0];//初始化
        memset(n, 0, sizeof(n));
        n[0] = 1;
        for (int i = 1; i < len; i++)
        {
            if (s[i] == c[cnt])n[cnt]++;
            else
            {
                cnt++;
                c[cnt] = s[i];
                n[cnt]++;
            }
        }
        for (int i = 0; i <= cnt; i++)
        {
            printf("(%c,%d)", c[i], n[i]);
        }
        return 0;
    }
    #include <cstdio>
    #include <cstring>
    using namespace std;
     
    int main()
    {
        char buf[1001];
        scanf("%s",buf);
        int len=strlen(buf);
        int i;
        for(i=0;i<len;i++){
            if(buf[i]>='A'&&buf[i]<='Z'){
                buf[i]+=32;
            }
        }
        i=0;
        char tmp;
        int cnt;
        while(i<len){
            tmp=buf[i];
            cnt=0;
            while(buf[i]==tmp){
                i++;
                cnt++;
            }
            printf("(%c,%d)",tmp,cnt);
        }
        printf("
    ");
        return 0;
    }
    变判断边输出

    C:岛屿周长

    解题思路

    简单题,深搜遍历上下左右的点,如果是海或者是边界,那么周长++。

    AC代码

    #include<cstdio>
    #include<cstring>
    
    int map[105][105];
    int mark[105][105] = { 0 };
    int n, m;
    int len = 0;
    int dx[4] = { 0,1,0,-1 };
    int dy[4] = { 1,0,-1,0 };
    
    bool valid(int x,int y)
    {
        return(x >= 0 && x < n && y >= 0 && y < m);
    }
    
    void DFS(int x,int y)
    {
        mark[x][y] = 1;
        for (int i = 0; i < 4; i++)
        {
            int newx = x + dx[i];
            int newy = y + dy[i];
            if (valid(newx, newy))
            {
                if (mark[newx][newy] == 0) DFS(newx, newy);
            }
            else len++;
        }
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++) scanf("%d", &map[i][j]);
        }
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                if (mark[i][j] == 1 || map[i][j] == 0)continue;
                DFS(i, j);
            }
        }
        printf("%d", len);
        return 0;
    }

    E:怪盗基德的滑翔翼

    解题思路

    简单题,因为可以任选一个方向,所以是正反都要做一次最长不上升子序列,等价于正序找最长不上升子序列和最长不下降子序列,然后取较大值。

    AC代码

    #include<cstdio>
    
    const int N = 105;
    int a[N];//记录原序列
    int dp[N];//dp[i]表示包括第i位之前序列的最长上升子序列长度
    int len;//原序列长度
    
    int LIS()
    {
        int tmp = 1;//返回值,表示整个序列的LIS值
        for (int i = 1; i <= len; i++)
        {
            dp[i] = 1;//都初始化为1,方便后面直接比较
            for (int j = 1; j < i; j++)
            {
                if (a[j] <= a[i] && dp[j] + 1 > dp[i]) dp[i] = dp[j] + 1;
            }
            if (dp[i] > tmp) tmp = dp[i];
        }
        return tmp;
    }
    
    int RLIS()
    {
        int tmp = 1;//返回值,表示整个序列的RLIS值
        for (int i = 1; i <= len; i++)
        {
            dp[i] = 1;//都初始化为1,方便后面直接比较
            for (int j = 1; j < i; j++)
            {
                if (a[j] >= a[i] && dp[j] + 1 > dp[i]) dp[i] = dp[j] + 1;
            }
            if (dp[i] > tmp) tmp = dp[i];
        }
        return tmp;
    }
    
    
    int main()
    {
        int T;
        scanf("%d", &T);
        while (T--)
        {
            scanf("%d", &len);
            for (int i = 1; i <= len; i++)scanf("%d", &a[i]);
            int a1 = LIS();
            int a2 = RLIS();
            int ans = a1 > a2 ? a1 : a2;
            printf("%d
    ", ans);
        }
        return 0;
    }

    G:实现堆结构

    解题思路

    使用优先队列。 

    AC代码

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <queue>
    #include <algorithm>
    using namespace std;
    
    priority_queue<int, vector<int>, greater<int> > q; // 小堆顶结构
    
    int main()
    {
        int t;
        scanf("%d", &t);
        for(int i=0; i<t; i++)
        {
            int n, type;
            scanf("%d", &n);
            for(int j=0; j<n; j++)
            {
                scanf("%d", &type);
                if(type == 1)
                {
                    int u;
                    scanf("%d", &u);
                    q.push(u);
                }
                if(type == 2)
                {
                    printf("%d
    ", q.top());
                    q.pop();
                }
            }
        }
        return 0;
    }

    D:Safecracker

    解题思路

    可以用五层循环,也可以用dfs。

    AC代码(五层循环暴搜解法)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    int toInt(char ch) 
    {
        return ch - 'A' + 1;
    }
    
    int target;
    char a[15];
    int main() 
    {
        while (scanf("%d%s", &target, a) && (target != 0 || strcmp(a, "END") != 0)) {
            sort(a, a + strlen(a));
            int sum;
            int flag = 0;
            string str;
            for (int i = 0; a[i]; i++) {
                for (int j = 0; a[j]; j++) {
                    for (int k = 0; a[k]; k++) {
                        for (int l = 0; a[l]; l++) {
                            for (int m = 0; a[m]; m++) {
                                if (i != j && i != k && i != l && i != m && j != k &&
                                    j != l && j != m && k != l && k != m && l != m) {
                                    sum = toInt(a[i]) - toInt(a[j]) * toInt(a[j]) + toInt(a[k]) *toInt(a[k]) *
                                        toInt(a[k]) - toInt(a[l]) *toInt(a[l]) * toInt(a[l]) *toInt(a[l]) + toInt(a[m]) *
                                        toInt(a[m]) *toInt(a[m]) *toInt(a[m]) * toInt(a[m]);
                                    if (sum == target) {
                                        flag = 1;
                                        str = "";
                                        str = str + a[i] + a[j] + a[k] + a[l] + a[m];
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (flag == 1) {
                printf("%s
    ", str.c_str());
            }
            else printf("no solution
    ");
        }
        return 0;
    }

    AC代码(DFS解法)

    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    int n;
    int len;
    char s[15];//存放原字符串
    int vis[15];//深搜访问标记
    int t[5];//存放最终字符串
    int p[5];//转换后的数字
    
    void check()//更新为最大字典序
    {
        for (int i = 0; i < 5; i++)
        {
            if (p[i] > t[i])
            {
                for (int j = 0; j < 5; j++)
                {
                    t[j] = p[j];
                }
                break;
            }
            if (p[i] < t[i])
            {
                break;
            }
        }
    }
    
    void dfs(int cur)
    {
        if (cur == 5)
        {
            if (n == p[0] - p[1] * p[1] + p[2] * p[2] * p[2] - p[3] * p[3] * p[3] * p[3] + p[4] * p[4] * p[4] * p[4] * p[4])
            {
                check();
            }
        }
        else
        {
            for (int i = 0; i < len; i++)//逐元素向前推进进行深搜
            {
                if (!vis[i])
                {
                    vis[i] = 1;
                    p[cur] = s[i] - 'A' + 1;
                    dfs(cur + 1);
                    vis[i] = 0;//回溯
                }
            }
        }
    }
    
    int main()
    {
        while (true)
        {
            cin >> n >> s;
            if (n == 0)
            {
                return 0;
            }
            len = strlen(s);
            memset(vis, 0, sizeof(vis));
            memset(t, 0, sizeof(t));
            memset(p, 0, sizeof(p));
            dfs(0);
            if (t[0] == 0)
            {
                cout << "no solution" << endl;
            }
            else
            {
                for (int i = 0; i < 5; i++)
                {
                    cout << (char)(t[i] + 'A' - 1);
                }
                cout << endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    STL 里出现 warning C4018: “<”: 有符号/无符号不匹配
    (程序员面试题精选(02))-设计包含min函数的栈
    C++的内存分配问题
    C++ const解析(转)
    关于QQ一些功能的实现(转)
    C++中堆和栈的完全解析(转)
    关于Windows的TortoiseSVN 不能Check out google 代码的问题
    WPF笔记(2.6 ViewBox)——Layout
    我也设计模式——0.前言
    WPF笔记(2.8 常用的布局属性)——Layout
  • 原文地址:https://www.cnblogs.com/yun-an/p/11108072.html
Copyright © 2011-2022 走看看