• PAT团体程序设计天梯赛


    由于本人愚笨,最后一题实在无力AC,于是只有前14题的题解Orz

    总的来说,这次模拟赛的题目不算难,前14题基本上一眼就有思路,但是某些题写起来确实不太容易,编码复杂度有点高~

    L1-1 N个数求和

    设计一个分数类,重载加法运算符,注意要约分,用欧几里得算法求个最大公约数即可。

     1 #include <cstdio>
     2 
     3 long long abs(long long x)
     4 {
     5     return x < 0 ? -x : x;
     6 }
     7 
     8 long long gcd(long long a, long long b)
     9 {
    10     if (b == 0)
    11         return a;
    12     else if (a > b)
    13         return gcd(b, a % b);
    14     else
    15         return gcd(a, b % a);
    16 }
    17 
    18 struct FS
    19 {
    20     long long fz, fm;
    21     FS(long long _fz = 0, long long _fm = 1)
    22     {
    23         fz = _fz;
    24         fm = _fm;
    25         if (fz & fm)
    26         {
    27             long long g = gcd(abs(fz), abs(fm));
    28             fz /= g;
    29             fm /= g;
    30         }
    31     }
    32     friend FS operator+ (const FS& a, const FS& b)
    33     {
    34         FS ans;
    35         long long lcm = a.fm / gcd(abs(a.fm), abs(b.fm)) * b.fm;
    36         ans.fz = a.fz * (lcm / a.fm) + b.fz * (lcm / b.fm);
    37         ans.fm = lcm;
    38         if (ans.fz && ans.fm)
    39         {
    40             long long g = gcd(abs(ans.fz), abs(ans.fm));
    41             ans.fz /= g;
    42             ans.fm /= g;
    43         }
    44         return ans;
    45     }
    46 };
    47 
    48 int main()
    49 {
    50     int n;
    51     scanf("%d", &n);
    52     FS ans;
    53     char buf[64];
    54     while (n--)
    55     {
    56         scanf("%s", buf);
    57         long long fz, fm;
    58         sscanf(buf, "%lld/%lld", &fz, &fm);
    59         ans = ans + FS(fz, fm);
    60     }
    61     if (ans.fz == 0)
    62         printf("0");
    63     else if (abs(ans.fz) < abs(ans.fm))
    64         printf("%lld/%lld", ans.fz, ans.fm);
    65     else
    66     {
    67         if (ans.fz % ans.fm == 0)
    68             printf("%lld", ans.fz / ans.fm);
    69         else
    70             printf("%lld %lld/%lld", ans.fz / ans.fm, ans.fz % ans.fm, ans.fm);
    71     }
    72     return 0;
    73 }


    L1-2 比较大小

    太水了,不解释,直接sort一下。

     1 #include <cstdio>
     2 #include <algorithm>
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     int a[3];
     8     scanf("%d%d%d", a, a + 1, a + 2);
     9     sort(a, a + 3);
    10     printf("%d->%d->%d", a[0], a[1], a[2]);
    11     return 0;
    12 }


    L1-3 A-B

    用一个bool数组记录第二个字符串中出现的字符,然后遍历第一个字符串,检测是否在第二个字符串中出现过。

     1 #include <cstdio>
     2 #include <algorithm>
     3 using namespace std;
     4 
     5 char s1[10010];
     6 char s2[10010];
     7 bool vis[128];
     8 
     9 int main()
    10 {
    11     gets(s1);
    12     gets(s2);
    13     int idx = -1;
    14     while (s2[++idx])
    15         vis[s2[idx]] = true;
    16     idx = -1;
    17     while (s1[++idx])
    18         if (!vis[s1[idx]])
    19             putchar(s1[idx]);
    20     return 0;
    21 }


    L1-4 计算指数

    太水了,直接左移位。

     1 #include <cstdio>
     2 #include <algorithm>
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     int n;
     8     scanf("%d", &n);
     9     printf("%d^%d = %d", 2, n, 1 << n);
    10     return 0;
    11 }


    L1-5 计算阶乘和

    太水了,求阶乘累加。

     1 #include <cstdio>
     2 #include <algorithm>
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     int n;
     8     scanf("%d", &n);
     9     int sum = 0;
    10     int fact = 1;
    11     for (int i = 1; i <= n; i++)
    12         sum += fact *= i;
    13     printf("%d", sum);
    14     return 0;
    15 }


    L1-6 简单题

    hello world同级别的题。

    1 #include <cstdio>
    2 int main() 
    3 {
    4     printf("This is a simple problem.");
    5     return 0;
    6 }


    L1-7 跟奥巴马一起画方块

    双重循环。

     1 #include <cstdio>
     2 #include <algorithm>
     3 using namespace std;
     4 
     5 int main()
     6 {
     7     int n;
     8     char c[2];
     9     scanf("%d%s", &n, c);
    10     for (int i = 0; i < (n + 1) / 2; i++, puts(""))
    11         for (int j = 0; j < n; j++)
    12             putchar(c[0]);
    13     return 0;
    14 }


    L1-8 查验身份证

    按规则模拟就好了,注意判断前17位有无非数字。

     1 #include <cstdio>
     2 #include <algorithm>
     3 using namespace std;
     4 
     5 int wei[] = {7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
     6 int rlt[] = {1,0,-1,9,8,7,6,5,4,3,2};
     7 
     8 bool check(char *s)
     9 {
    10     int sum = 0;
    11     for (int i = 0; i < 17; i++)
    12     {
    13         if (!isdigit(s[i]))
    14             return false;
    15         sum += (s[i] - '0') * wei[i];
    16     }
    17     sum %= 11;
    18     if (rlt[sum] == -1)
    19         return s[17] == 'X';
    20     else
    21         return s[17] - '0' == rlt[sum];
    22 }
    23 
    24 int main()
    25 {
    26     int n;
    27     char s[20];
    28     scanf("%d", &n);
    29     bool allpass = true;
    30     while (n--)
    31     {
    32         scanf("%s", s);
    33         if (!check(s))
    34         {
    35             puts(s);
    36             allpass = false;
    37         }
    38     }
    39     if (allpass)
    40         puts("All passed");
    41     return 0;
    42 }


    L2-1 集合相似度

    排序后,对于每个询问二分好像会超时一组数据。那么我们可以把那些数字离散化&去重之后,用hash思想来做,O(M)复杂度处理每个查询。

     1 #include <cstdio>
     2 #include <algorithm>
     3 using namespace std;
     4 
     5 int sorted[500010];
     6 int sset[60][10010];
     7 bool vis[500010];
     8 int rec[20010];
     9 
    10 int main()
    11 {
    12     int n;
    13     scanf("%d", &n);
    14     int tot = 0;
    15     for (int i = 0; i < n; i++)
    16     {
    17         scanf("%d", &sset[i][0]);
    18         for (int j = 1; j <= sset[i][0]; j++)
    19             scanf("%d", &sset[i][j]), sorted[tot++] = sset[i][j];
    20         sort(sset[i] + 1, sset[i] + 1 + sset[i][0]);
    21         sset[i][0] = unique(sset[i] + 1, sset[i] + 1 + sset[i][0]) - sset[i] - 1;
    22     }
    23     sort(sorted, sorted + tot);
    24     tot = unique(sorted, sorted + tot) - sorted;
    25     for (int i = 0; i < n; i++)
    26         for (int j = 1; j <= sset[i][0]; j++)
    27             sset[i][j] = lower_bound(sorted, sorted + tot, sset[i][j]) - sorted;
    28     int k;
    29     scanf("%d", &k);
    30     while (k--)
    31     {
    32         int a, b;
    33         scanf("%d%d", &a, &b);
    34         a--, b--;
    35         int nc = 0, nt = 0;
    36         int reccnt = 0;
    37         for (int i = 1; i <= sset[a][0]; i++)
    38             vis[sset[a][i]] = true, rec[reccnt++] = sset[a][i];
    39         nt = sset[a][0];
    40         for (int i = 1; i <= sset[b][0]; i++)
    41         {
    42             rec[reccnt++] = sset[b][i];
    43             if (vis[sset[b][i]])
    44                 nc++;
    45             else
    46                 nt++;
    47         }
    48         for (int i = 0; i < reccnt; i++)
    49             vis[rec[i]] = false;
    50         printf("%.2f%
    ", 1.0 * nc / nt * 100);
    51     }
    52     return 0;
    53 }


    L2-2 树的遍历

    后序序列最后一个是根节点,用那个根节点把中序序列分开,然后递归建树,最后再宽搜一下。

     1 #include <cstdio>
     2 #include <vector>
     3 #include <queue>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 vector<int> tree[40];
     8 int n;
     9 int hx[40];
    10 int zx[40];
    11 
    12 int deal(int lz, int rz, int lh, int rh)
    13 {
    14     if (lz > rz || lh > rh)
    15         return -1;
    16     int root = hx[rh];
    17     int pos = find(zx + lz, zx + rz + 1, root) - zx;
    18     int cnt = pos - lz;
    19     tree[root].push_back(deal(lz, pos - 1, lh, lh + cnt - 1));
    20     tree[root].push_back(deal(pos + 1, rz, lh + cnt, rh - 1));
    21     return root;
    22 }
    23 
    24 int main()
    25 {
    26     scanf("%d", &n);
    27     for (int i = 0; i < n; i++)
    28         scanf("%d", hx + i);
    29     for (int i = 0; i < n; i++)
    30         scanf("%d", zx + i);
    31     int root = deal(0, n - 1, 0, n - 1);
    32     queue<int> q;
    33     q.push(root);
    34     bool flag = false;
    35     while (!q.empty())
    36     {
    37         int cur = q.front();
    38         q.pop();
    39         if (flag)
    40             printf(" %d", cur);
    41         else
    42             printf("%d", cur), flag = true;
    43         if (tree[cur][0] != -1)
    44             q.push(tree[cur][0]);
    45         if (tree[cur][1] != -1)
    46             q.push(tree[cur][1]);
    47     }
    48     return 0;
    49 }


    L2-3 家庭房产

    思路很简单,就是普通的并查集,但是代码不太好写哦~

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    struct Node
    {
        int parent;
        int ts, mj;
    };
    struct Result
    {
        int minid;
        int siz;
        int ts, mj;
        friend bool operator< (const Result& a, const Result& b)
        {
            if (1LL * a.mj * b.siz == 1LL * b.mj * a.siz)
                return a.minid < b.minid;
            return 1LL * a.mj * b.siz > 1LL * b.mj * a.siz;
        }
    };
    Node node[10010];
    Result rlt[10010];
    
    int uf_find(int x)
    {
        if (node[x].parent == x)
            return x;
        return node[x].parent = uf_find(node[x].parent);
    }
    
    void uf_union(int x, int y)
    {
        x = uf_find(x);
        y = uf_find(y);
        if (x != y)
            node[x].parent = y;
    }
    
    int main()
    {
        int n;
        scanf("%d", &n);
        for (int i = 0; i < 10000; i++)
            node[i].parent = i, rlt[i].minid = 1000000;
        while (n--)
        {
            int id, f, m, k, hz;
            scanf("%d%d%d%d", &id, &f, &m, &k);
            if (f != -1)
                uf_union(f, id);
            if (m != -1)
                uf_union(m, id);
            for (int i = 0; i < k; i++)
            {
                scanf("%d", &hz);
                uf_union(hz, id);
            }
            scanf("%d%d", &node[id].ts, &node[id].mj);
        }
        for (int i = 0; i < 10000; i++)
        {
            int x = uf_find(i);
            rlt[x].minid = min(rlt[x].minid, i);
            rlt[x].ts += node[i].ts;
            rlt[x].mj += node[i].mj;
            rlt[x].siz++;
        }
        sort(rlt, rlt + 10000);
        int cnt = 0;
        for (int i = 0; i < 10000; i++)
        {
            if (rlt[i].mj != 0)
                cnt++;
            else
                break;
        }
        printf("%d
    ", cnt);
        for (int i = 0; i < cnt; i++)
        {
            if (rlt[i].mj != 0)
                printf("%04d %d %.3f %.3f
    ", rlt[i].minid, rlt[i].siz,
                       1.0 * rlt[i].ts / rlt[i].siz, 1.0 * rlt[i].mj / rlt[i].siz);
        }
        return 0;
    }


    L2-4 最长对称子串

    枚举回文中点,向两边扩展枚举。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 char s[1010];
     7 
     8 int main()
     9 {
    10     gets(s);
    11     int len = strlen(s);
    12     int ans = 0;
    13     for (int i = 0; i < len; i++)
    14     {
    15         int l = i, r = i;
    16         int curans = 0;
    17         while (l >= 0 && r < len && s[l] == s[r])
    18             curans += 2, l--, r++;
    19         ans = max(ans, curans - 1);
    20         if (i < len - 1 && s[i] == s[i + 1])
    21         {
    22             l = i;
    23             r = l + 1;
    24             curans = 0;
    25             while (l >= 0 && r < len && s[l] == s[r])
    26                 curans += 2, l--, r++;
    27             ans = max(ans, curans);
    28         }
    29     }
    30     printf("%d", ans);
    31     return 0;
    32 }


    L3-1 肿瘤诊断

    三维的图找连通块,道理和二维一样,注意这里只能宽搜。

     1 #include <cstdio>
     2 #include <queue>
     3 using namespace std;
     4 
     5 bool pic[61][1287][129];
     6 bool vis[61][1287][129];
     7 int dx[] = {1,-1,0,0,0,0};
     8 int dy[] = {0,0,-1,1,0,0};
     9 int dz[] = {0,0,0,0,1,-1};
    10 int m, n, l, t;
    11 
    12 int bfs(int z, int x, int y)
    13 {
    14     queue<int> q;
    15     q.push(z * (m * n) + x * n + y);
    16     vis[z][x][y] = true;
    17     int cnt = 0;
    18     while (!q.empty())
    19     {
    20         cnt++;
    21         int cur = q.front();
    22         q.pop();
    23         z = cur / (m * n);
    24         cur %= m * n;
    25         x = cur / n;
    26         y = cur % n;
    27         for (int i = 0; i < 6; i++)
    28         {
    29             int zz = z + dz[i];
    30             int xx = x + dx[i];
    31             int yy = y + dy[i];
    32             if (zz < 0 || zz >= l)
    33                 continue;
    34             if (xx < 0 || xx >= m)
    35                 continue;
    36             if (yy < 0 || yy >= n)
    37                 continue;
    38             if (pic[zz][xx][yy] && !vis[zz][xx][yy])
    39             {
    40                 vis[zz][xx][yy] = true;
    41                 q.push(zz * (m * n) + xx * n + yy);
    42             }
    43         }
    44     }
    45     return cnt;
    46 }
    47 
    48 int main()
    49 {
    50     scanf("%d%d%d%d", &m, &n, &l, &t);
    51     for (int i = 0; i < l; i++)
    52         for (int j = 0; j < m; j++)
    53             for (int k = 0; k < n; k++)
    54             {
    55                 int v;
    56                 scanf("%d", &v);
    57                 pic[i][j][k] = v == 1;
    58             }
    59     int ans = 0;
    60     for (int i = 0; i < l; i++)
    61         for (int j = 0; j < m; j++)
    62             for (int k = 0; k < n; k++)
    63             {
    64                 if (!vis[i][j][k] && pic[i][j][k])
    65                 {
    66                     int cnt = bfs(i, j, k);
    67                     if (cnt >= t)
    68                         ans += cnt;
    69                 }
    70             }
    71     printf("%d", ans);
    72     return 0;
    73 }


    L3-2 垃圾箱分布

    跑m次spfa就好了,注意结果四舍五入~

     1 #include <cstdio>
     2 #include <vector>
     3 #include <queue>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const long long inf = 1LL << 62;
     8 vector<pair<int, int> > G[1020];
     9 long long dis[1020];
    10 bool inqueue[1020];
    11 int n, m, k;
    12 long long ds;
    13 long long ansdis = -1;
    14 double avgdis = 1e30;
    15 int ansid = -1;
    16 
    17 void spfa(int s)
    18 {
    19     fill(dis, dis + 1020, inf);
    20     queue<int> q;
    21     q.push(s);
    22     dis[s] = 0;
    23     while (!q.empty())
    24     {
    25         int cur = q.front();
    26         q.pop();
    27         inqueue[cur] = false;
    28         for (int i = 0; i < G[cur].size(); i++)
    29         {
    30             if (dis[cur] + G[cur][i].second < dis[G[cur][i].first])
    31             {
    32                 dis[G[cur][i].first] = dis[cur] + G[cur][i].second;
    33                 if (!inqueue[G[cur][i].first])
    34                 {
    35                     inqueue[G[cur][i].first] = true;
    36                     q.push(G[cur][i].first);
    37                 }
    38             }
    39         }
    40     }
    41     long long mindis = *min_element(dis + 1, dis + n + 1);
    42     long long maxdis = *max_element(dis + 1, dis + n + 1);
    43     if (maxdis > ds)
    44         return;
    45     double sum = 0.0;
    46     for (int i = 1; i <= n; i++)
    47         sum += dis[i];
    48     sum /= n;
    49     if (mindis > ansdis)
    50     {
    51         ansdis = mindis;
    52         avgdis = sum;
    53         ansid = s;
    54     }
    55     else if (mindis == ansdis)
    56     {
    57         if (avgdis - sum > 1e-9)
    58         {
    59             ansdis = mindis;
    60             avgdis = sum;
    61             ansid = s;
    62         }
    63     }
    64 }
    65 
    66 int main()
    67 {
    68     scanf("%d%d%d%lld", &n, &m, &k ,&ds);
    69     for (int i = 0; i < k; i++)
    70     {
    71         char s1[10], s2[10];
    72         int a, b, d;
    73         scanf("%s%s%d", s1, s2, &d);
    74         if (s1[0] == 'G')
    75             sscanf(s1 + 1, "%d", &a), a += n;
    76         else
    77             sscanf(s1, "%d", &a);
    78         if (s2[0] == 'G')
    79             sscanf(s2 + 1, "%d", &b), b += n;
    80         else
    81             sscanf(s2, "%d", &b);
    82         G[a].push_back(make_pair(b, d));
    83         G[b].push_back(make_pair(a, d));
    84     }
    85     for (int i = n + 1; i <= n + m; i++)
    86         spfa(i);
    87     if (ansid == -1)
    88         puts("No Solution");
    89     else
    90     {
    91         avgdis *= 10.0;
    92         avgdis += 0.5;
    93         avgdis = floor(avgdis);
    94         avgdis /= 10.0;
    95         printf("G%d
    %.1lf %.1lf", ansid - n, 1.0 * ansdis, avgdis);
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    flask框架中SQLAlchemy相关
    flask使用外部存储模块之数据库的使用
    flask的基础知识
    docker的下载和使用
    rbac权限管理系统的学习
    redis数据库之五种数据类型的简单操作
    使用django框架进行web项目开发需要了解的知识
    django项目常用外部模块下载和使用
    pwn学习之dl_resolve学习篇
    验证docker的Redis镜像也存在未授权访问漏洞
  • 原文地址:https://www.cnblogs.com/iRedBean/p/5500077.html
Copyright © 2020-2023  润新知