【算法】【PAT】1051-1060

点击前往【PAT甲级之路总纲】

1051 Pop Sequence (25分) 推荐:2星

题目

在这里插入图片描述Sample Input:

5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2

Sample Output:

YES
NO
NO
YES
NO

分析

推荐:2星
两种方法:

  1. 模拟堆栈: vector来保留结果,stack来存序列数
  2. 找规律 : 计数小于的堆顶的maxcnt, 指向top, 指向tmp,指向cnt

题解

模拟堆栈

#include <iostream>
#include <stack>
#include <vector>
using namespace std;
int main(){
#ifndef ONLINE_JUDGE
    freopen("data.txt", "r", stdin);
#endif // ONLINE_JUDGE
    int m, n, k;
    scanf("%d%d%d", &m,&n,&k);
    for (int i = 0; i < k; i++){ ///检查每个序列是否能实现
        bool flag = false;
        stack<int> s; ///栈数据
        vector<int> v(n+1); ///需要匹配的队列
        for(int j = 1; j <= n;j++)
            scanf("%d", &v[j]);///从1开始
        int current = 1;
        for(int j = 1; j <= n; j++){
            s.push(j);
            if(s.size() > m) break; ///爆栈都没有符合
            while(!s.empty() && s.top() == v[current]){ ///匹配值成立
                s.pop();
                current++;
            }
        }
        if(current == n+1) flag = true; ///成功匹配
        if (flag) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

找规律

#include <iostream>
using namespace std;
int main(){
#ifndef ONLINE_JUDGE
    freopen("data.txt", "r", stdin);
#endif // ONLINE_JUDGE
    int m, n, k;
    scanf("%d %d %d", &m, &n, &k);
    for(int i = 0; i < k; i++){
        int tmp, cur, top, cnt = 1, flag=1, maxCnt = 0;
        scanf("%d", &top);
        cur = top;
        for(int j = 1; j < n; j++){
            scanf("%d", &tmp);
            if(tmp < top){
                cnt++;
                if(tmp > cur) flag = 0;
            }else{
                top = tmp;
                cnt = 1;
            }
            cur = tmp;
            maxCnt = max(maxCnt, cnt);
        }
        if (maxCnt > m) flag = 0;
        if (flag) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

1052 Linked List Sorting (25分) 推荐:1星

题目

在这里插入图片描述Sample Input:

5 00001
11111 100 -1
00001 0 22222
33333 100000 11111
12345 -1 33333
22222 1000 12345

Sample Output:

5 12345
12345 -1 00001
00001 0 11111
11111 100 22222
22222 1000 33333
33333 100000 -1

分析

推荐:1星
静态链表数组,常考。
要同一条链上,也就是说需要记录是否在一条链上,同时可遍历该链
需要做到,排序和记录

题解

#include <iostream>
#include <algorithm>
using namespace std;
struct NODE{
    int address, key, next;
    bool flag;
}node[100000];
int cmp1(NODE a, NODE b){
    return !a.flag || !b.flag ? a.flag > b.flag : a.key < b.key; /// 将无效的flag放在后面, 然后再进行排序
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("data.txt", "r", stdin);
    #endif // ONLINE_JUDGE
    int n, cnt = 0, s, a, b, c;
    scanf("%d%d", &n, &s);
    for(int i = 0; i<n; i++){ ///数据初始化
        scanf("%d%d%d", &a, &b, &c);
        node[a] = {a, b, c, false};
    }
    for(int i = s; i != -1; i = node[i].next){
        node[i].flag = true;
        cnt++;
    }
    if (cnt == 0){
        printf("0 -1");
    }else{
        sort(node, node + 100000, cmp1);
        printf("%d %05d\n", cnt, node[0].address);
        for(int i = 0; i < cnt; i++){
            printf("%05d %d ", node[i].address, node[i].key);
            if(i != cnt - 1)
                printf("%05d\n", node[i+1].address);
            else
                printf("-1\n");
        }
    }
    return 0;
}

1053 Path of Equal Weight (30分) 推荐:经典

题目

在这里插入图片描述在这里插入图片描述Sample Input:

20 9 24
10 2 4 3 5 10 2 18 9 7 2 2 1 3 12 1 8 6 2 2
00 4 01 02 03 04
02 1 05
04 2 06 07
03 3 11 12 13
06 1 09
07 2 08 10
16 1 15
13 3 14 16 17
17 2 18 19

Sample Output:

10 5 2 7
10 4 10
10 3 3 6 2
10 3 3 6 2

分析

推荐:经典
dfs的题,存储权重的方法,可用结构体,也可另存数组

题解

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int target;
struct NODE{
    int w;
    vector<int> child;
};
vector<NODE> v;
vector<int> path;
void dfs(int index, int nodeNum, int sum){  ///当前节点,下一个节点,加上当前节点的综合
    if(sum > target) return; ///边界条件
    if(sum == target){ /// 符合条件,添加路径
        if(v[index].child.size() != 0) return; ///还有子节点,不成立,放回
        for(int i = 0; i < nodeNum; i++) ///
            printf("%d%c", v[path[i]].w, i != nodeNum -1 ? ' ':'\n');
        return ;
    }
    for(int i = 0; i < v[index].child.size(); i++){
        int node = v[index].child[i];
        path[nodeNum] = node;
        dfs(node, nodeNum + 1, sum + v[node].w);
    }
}
int cmp1(int a, int b){
    return v[a].w > v[b].w;
}
int main(){
#ifndef ONLINE_JUDGE
    freopen("data.txt", "r", stdin);
#endif // ONLINE_JUDGE
    int n, m, node, k;
    scanf("%d%d%d", &n, &m, &target);
    v.resize(n), path.resize(n);
    for(int i = 0; i < n; i++)
        scanf("%d", &v[i].w);
    for(int i = 0; i < m; i++){
        scanf("%d %d", &node, &k);
        v[node].child.resize(k); ///设置Child尺寸
        for(int j=0; j < k; j++)
            scanf("%d", &v[node].child[j]); ///存储下标
        sort(v[node].child.begin(), v[node].child.end(), cmp1); ///下降排序
    }
    dfs(0, 1, v[0].w); ///多节点深度搜索
    return 0;
}

1054 The Dominant Color (20分)

题目

在这里插入图片描述Sample Input:

5 3
0 0 255 16777215 24
24 24 0 0 24
24 0 24 24 24

Sample Output:

24

题解

#include <iostream>
#include <unordered_map>
using namespace std;
int main(){
#ifndef ONLINE_JUDGE
    freopen("data.txt", "r", stdin);
#endif // ONLINE_JUDGE
    int m, n, t;
    unordered_map<int, int> book;
    scanf("%d %d", &m, &n);
    int mid = (m * n)/2;
    for(int i = 0; i < m; i++){
        for(int j = 0; j < n; j++){
            scanf("%d", &t);
            book[t]++;
            if(book[t] > mid){
                printf("%d", t);
                break;
            }
        }
    }
    return 0;
}

1055 The World‘s Richest (25分)

题目

在这里插入图片描述Sample Input:

12 4
Zoe_Bill 35 2333
Bob_Volk 24 5888
Anny_Cin 95 999999
Williams 30 -22
Cindy 76 76000
Alice 18 88888
Joe_Mike 32 3222
Michael 5 300000
Rosemary 40 5888
Dobby 24 5888
Billy 24 5888
Nobody 5 0
4 15 45
4 30 35
4 5 95
1 45 50

Sample Output:

Case #1:
Alice 18 88888
Billy 24 5888
Bob_Volk 24 5888
Dobby 24 5888
Case #2:
Joe_Mike 32 3222
Zoe_Bill 35 2333
Williams 30 -22
Case #3:
Anny_Cin 95 999999
Michael 5 300000
Alice 18 88888
Cindy 76 76000
Case #4:
None

题解

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
struct node{
    char name[10];
    int age, money;
};
int cmp1(node a, node b){
    if (a.money != b.money)
        return a.money > b.money;
    else if (a.age != b.age)
        return a.age < b.age;
    else
        return (strcmp(a.name, b.name) < 0);
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("data.txt", "r", stdin);
    #endif // ONLINE_JUDGE
    int n, k, num, amin, amax;
    scanf("%d %d", &n, &k);
    vector<node> vt(n), v;
    vector<int> book(205, 0);
    for (int i = 0; i < n; i++)
        scanf("%s %d %d", vt[i].name, &vt[i].age, &vt[i].money);
    sort(vt.begin(), vt.end(), cmp1);
    for(int i = 0; i < n; i++){
        if(book[vt[i].age] < 100){
            v.push_back(vt[i]);
            book[vt[i].age]++;
        }
    }
    for(int i = 0; i < k; i++){
        scanf("%d%d%d", &num, &amin, &amax);
        vector<node> t;
        for(int j = 0; j < v.size(); j++){
            if(v[j].age >= amin && v[j].age <= amax)
                t.push_back(v[j]);
        }
        if(i != 0) printf("\n");
        printf("Case #%d:", i+1);
        int flag = 0;
        for (int j = 0; j < num && j < t.size(); j++){
            printf("\n%s %d %d", t[j].name, t[j].age, t[j].money);
            flag = 1;
        }
        if (flag == 0) printf("\nNone");
    }
    return 0;
}

1056 Mice and Rice (25分) 推荐:2星

题目

在这里插入图片描述Sample Input:

11 3
25 18 0 46 37 3 19 22 57 56 10
6 0 8 7 10 5 9 1 4 2 3

Sample Output:

5 5 5 2 5 5 5 3 1 3 5

分析

模拟题
推荐:2星
用数组来记录映射太多,容易混乱,比较适合用结构体

题解

#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
struct node{
    int weight, index, rank, index0;
};
bool cmp1(node a, node b){
    return a.index0 < b.index0;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("data.txt", "r", stdin);
    #endif // ONLINE_JUDGE
    int n, g, num;
    scanf("%d%d", &n, &g);
    vector<int> v(n);
    vector<node> w(n);
    for(int i = 0; i < n; i++)
        scanf("%d", &v[i]);
    for (int i = 0; i < n; i++){
        scanf("%d", &num);
        w[i].weight = v[num];
        w[i].index = i; ///比赛序
        w[i].index0 = num; ///在原数组中所处位置
    }
    queue<node> q;
    for (int i = 0; i < n; i++)
        q.push(w[i]);
    while(!q.empty()){
        int size = q.size();
        if (size == 1){ ///只剩一个
            node temp = q.front();
            w[temp.index].rank = 1;
            break;
        }
        int group = size/g; ///比赛小组数
        if(size % g != 0)
            group += 1;
        node maxnode;
        int maxn = -1, cnt = 0; ///每一组最大值,小组内参赛者数
        for (int i = 0; i < size; i++){
            node temp = q.front();
            w[temp.index].rank = group + 1; /// 第一轮失败者的排名
            q.pop();
            cnt++;
            if (temp.weight > maxn){
                maxn = temp.weight;
                maxnode = temp;
            }
            if (cnt == g || i == size - 1){ ///两个终止条件
                cnt = 0;
                maxn = -1;
                q.push(maxnode);
            }
        }
    }
    sort(w.begin(), w.end(), cmp1);
    for(int i = 0; i < n; i++){
        if( i != 0) printf(" ");
        printf("%d", w[i].rank);
    }
    return 0;
}

1057 Stack (30分) 推荐:2星

题目

在这里插入图片描述Sample Input:

17
Pop
PeekMedian
Push 3
PeekMedian
Push 2
PeekMedian
Push 1
PeekMedian
Pop
Pop
Push 5
Push 4
PeekMedian
Pop
Pop
Pop
Pop

Sample Output:

Invalid
Invalid
3
2
2
1
2
4
4
5
3
Invalid

分析

推荐:2星
堆栈模拟,输出中位数(可以用桶排序和树状数组,当前数据用的是桶排序)

题解

#include<iostream>
#include<stack>
#include<cstring>
using namespace std;
const int maxn = 1e5 + 10;
const int sqrtN = 316;
int block[sqrtN], table[maxn];
int n;
stack<int>s;
void Pop()
{
    int x = s.top();
    s.pop();
    table[x]--;
    block[x / sqrtN]--;
    printf("%d\n", x);
}
void Push(int x)
{
    s.push(x);
    table[x]++;
    block[x / sqrtN]++;
}
void PeekMedian(int k) ///核心:找到第k个数
{
    int sum = 0, idx = 0;
    while (sum + block[idx] < k)
        sum += block[idx++];
    int num = sqrtN*idx;
    while (sum + table[num] < k)
        sum += table[num++];
    printf("%d\n", num);
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("data.txt", "r", stdin);
    #endif // ONLINE_JUDGE
    scanf("%d", &n);
    while (n--)
    {
        char ss[30];
        scanf("%s", ss);
        int num;
        if (ss[1] == 'o')
        {
            if (s.size() == 0)printf("Invalid\n");
            else Pop();
        }
        else if (ss[1] == 'e')
        {
            if (s.size() == 0)printf("Invalid\n");
            else
            {
                int k;
                if (s.size() % 2 == 0)k = s.size() / 2;
                else k = (s.size() + 1) / 2;
                PeekMedian(k);
            }
        }
        else if(ss[1]=='u')
        {
            scanf("%d", &num);
            Push(num);
        }
    }
    return 0;
}

1058 A+B in Hogwarts (20分)

题目

在这里插入图片描述Sample Input:

3.2.1 10.16.27

Sample Output:

14.1.28

分析

涉及进制,则将数转换为最小单位来计算,时间也是如此

题解

#include <iostream>
using namespace std;

int main(){
#ifndef ONLINE_JUDGE
    freopen("data.txt", "r", stdin);
#endif // ONLINE_JUDGE
    long long a, b, c, d, e, f;
    scanf("%lld.%lld.%lld %lld.%lld.%lld", &a, &b, &c, &d, &e, &f);
    long long num = c + b*29 + a*29*17 + f + e * 29 + d * 29*17;
    long long g = num / (17*29);
    num = num % (17*29);
    printf("%lld.%lld.%lld", g, num/29, num%29);
    return 0;
}

1059 Prime Factors (25分) 推荐:2星

题目

在这里插入图片描述Sample Input:

97532468

Sample Output:

97532468=2^2*11*17*101*1291

分析

推荐:2星
生成素数表,并输出因子公式。

要点

  • bool primes[10000] 初始化,只能赋值0, 或者false
  • long int 其实就是int
  • int的范围 : -2147483648 ~ 2147483647
  • 注意: 考虑1的情况
  • 这个的精华在于循环的条件: n >= 2

题解

#include <cstdio>
#include <vector>
using namespace std;
vector<int> prime(500000, 1);
int main(){
    for(int i = 2; i * i < 500000; i++){ ///找素数
        if(prime[i] == 1){
            for(int j = 2; j * i < 500000; j++)
                prime[j*i] = 0;
        }
    }
    #ifndef ONLINE_JUDGE
    freopen("data.txt", "r", stdin);
    #endif // ONLINE_JUDGE
    long int a;
    scanf("%ld", &a);
    printf("%ld=", a);
    if (a == 1) printf("1");
    bool state = false;
    for(int i = 2; a >= 2; i++){ ///如果还有值
        int cnt = 0, flag = 0;
        while(prime[i] == 1 &&a % i == 0){
            cnt ++;
            a = a / i;
            flag = 1;
        }
        if (flag){
            if(state) printf("*");
            printf("%d", i);
            state = true;
        }
        if(cnt >= 2)
            printf("^%d", cnt);
    }
    return 0;
}

1060 Are They Equal (25分) 推荐:2星

题目

在这里插入图片描述Sample Input 1:

3 12300 12358.9

Sample Output 1:

YES 0.123*10^5

Sample Input 2:

3 120 128

Sample Output 2:

NO 0.120*10^3 0.128*10^3

分析

推荐:2星
条件分开遍历。
本质上是道模拟题,要想到各种情况,落实到纸面,只要推出公式,就可完成。

题解

#include <cstdio>
#include <cstring>
using namespace std;
int n;
char C[10000], A[10000], B[10000];
int trimStr(char *t, char *d){
    int cnt = strlen(t), q = 0, index = 0;
    for(int i = 0; i < strlen(t); i++){
        if (t[i] == '.'){
            cnt = i;
            break;
        }
    }
    while( t[q] == '0' || t[q] == '.') q++; ///跳掉无效数据
    if(cnt >= q)
        cnt = cnt - q;
    else cnt = cnt - q + 1; ///更新有效数据
    if (q == strlen(t)) cnt = 0; ///特判0
    while(index < n){ ///找到n个有效数, 找不到则填0
        if(t[q] != '.' && q < strlen(t))
            d[index++] = t[q];
        else if (q >= strlen(t))
            d[index++] = '0';
        q++;
    }
    return cnt;
}
int main(){
#ifndef ONLINE_JUDGE
    freopen("data.txt", "r", stdin);
#endif // ONLINE_JUDGE
    scanf("%d %s", &n, C);
    int cnta = trimStr(C, A);
    scanf("%s", C);
    int cntb = trimStr(C, B);
    if(strcmp(A, B) == 0 && cnta == cntb)
        printf("YES 0.%s*10^%d", A, cnta);
    else
        printf("NO 0.%s*10^%d 0.%s*10^%d", A, cnta, B, cntb);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值