PAT 520 钻石争霸赛 2022(96)

在这里插入图片描述

分析

前5题还好,20min解决。后3题都卡了,记录一下。

7-6 非诚勿扰

思路

  • 根据n和题意计算r = n / 2.718
  • 依次输入分数,记录前r个数字的最大值的位置。
  • 从第r+1个位置开始找比前r个数字最大值大的元素的位置,记ans1。
  • 输入分数的同时,记录出现最大分数的出现位置,记为ans2。
  • 按要求输出。

总结

  • 卡在第一次写代码记录的是最大值而不是最大值对应下标,导致花了点时间修改。
  • 对于这种题目通过下标找对应最大值是随机存取O(1)即可完成。所以以后每次该记录最大值对应下标,而非最大值。

7-7 新式六合彩

思路

  • 先根据给出的行列上限,将n * m个数字存入数组rec[n + 1][m + 1]
  • 然后根据给出的行r列c遍历对应m+n-1个元素。
  • 每次判断元素是否存在、是否更接近目标值。

总结

  • 卡在把-写成了=,debug10min……

7-8 521序列(代码待测试)

思路

  • 用一个multiset存出现的元素,一个map记录元素出现次数
  • 因为map是顺序存储的,所以遍历其中元素j,如果对应3个元素j、j * 2、j * 5 都存在则删除,并插入multiset。
  • 遍历multiset输出到deque,然后按要求输出。

总结

  • 感觉时间不够,结果慌乱中写错了逻辑,导致只得了1分。慢点,别看时间。

7-6 非诚勿扰

题解

#include<bits/stdc++.h>
using namespace std;
int n, a[10001], r, ptr_p, ptr, ans;
int main(){
    cin>>n;
    r = n / 2.718;
    bool flag = false;
    for(int i = 1; i <= n; i ++){
        scanf("%d", &a[i]);
        if(i <= r){
            if(a[ptr_p] < a[i]){
                ptr_p = i;
                ptr = i;
            }
        }
        if(i > r){
            if(flag == false && a[i] > a[ptr_p]) flag = true, ans = i;
            if(a[i] > a[ptr]) ptr = i;
        }
    }
    printf("%d %d\n", ans, ptr);
    return 0;
}

fcwr.JPG

题目

“非诚勿扰”是江苏台一款非常受欢迎的相亲节目,台上的女嘉宾们可以从出场的男嘉宾中选择自己喜欢的牵手离开。问题是怎样才能选到最适合自己的男嘉宾呢?这是个概率问题。

解决这个问题有一种随机算法:假设女嘉宾知道自己最多能在台上录几期节目,也就知道自己最多能见到 N 位男嘉宾,那么她可以选择一个随机数 R(<N),对她见到的前 R 位男嘉宾,一个都不牵,只是以他们中最合适的那位作为一个标准,从第 R+1 位男嘉宾开始,只要遇到一个比标准更合适的,就决定牵手。理论上可以证明,当 R=N/e (其中 e 是自然常数,约等于 2.718)时,这样做能牵手最合适的男嘉宾的概率最高。

本题就请你根据男嘉宾的出场顺序,预测一下女嘉宾会牵手哪一位。

输入格式:

输入首先在第一行中给出正整数 N(3≤N≤104),即男嘉宾的数量。第二行给出 N 个互不相同的正整数,第 i 个数字表示第 i 位男嘉宾在女嘉宾心目中的得分。数字均不超过 105,之间以空格分隔。

输出格式:

女嘉宾将以 R=⌊N/e⌋ 为线,采用题面中描述的算法选择牵手的男嘉宾。这里我们取 e=2.718。请在一行中输出她牵手的男嘉宾的序号和真正最适合她的男嘉宾的序号(从 1 开始),数字间以 1 个空格分隔。

如果她一直没有遇到比标准更合适的人,就会独自离开,此时对应的序号输出为 0

输入样例 1:

10
23 84 15 29 17 56 85 40 91 28

输出样例 1:

7 9

输入样例 2:

10
56 85 17 23 84 15 29 40 31 28

输出样例 2:

0 2

7-7 新式六合彩

题解

#include<bits/stdc++.h>
using namespace std;
int m, n, r, c, f, a[1001][1001], sub = INT_MAX;
vector<pair<int, int>> ans;
int main(){
    cin>>n>>m;
    for(int i = 1; i <= n; i ++){
        for(int j = 1; j <= m; j ++){
            scanf("%d", &a[i][j]);
        }
    }
    cin>>r>>c>>f;
    for(int i = 1; i <= m; i++){
        if(a[r][i] == -1) continue;
        if(abs(a[r][i] - f) == sub){
            ans.push_back({r, i});
        }else if(abs(a[r][i] - f) < sub){
            ans.clear();
            ans.push_back({r, i});
            sub = abs(a[r][i] - f);
        }
    }
    for(int i = 1; i <= n; i++){
        if(a[i][c] == -1) continue;
        if(i == r) continue;
        if(abs(a[i][c] - f) == sub)
            ans.push_back({i, c});
        else if(abs(a[i][c] - f) < sub){
            ans.clear();
            ans.push_back({i, c});
            sub = abs(a[i][c] - f);
        }
    }
    for(auto i : ans)
        printf("(%d:%d)\n", i.first, i.second);
    return 0;
}

题目

新式六合彩跟传统六合彩其实没有半点关系,只是姥姥为了出题杜撰出来的一种玩法——每位玩家可以下注一个六位数,如果跟开出来的幸运六位数最接近就可以获奖(所谓最接近,是指该数字与幸运数之差的绝对值最小)。

但规则如果这么简单就没什么可玩的了…… 我们把规则搞复杂一点:首先创建一个有 n×m 个格子的矩阵,保证格子总数不小于玩家总数,可以把所有玩家下注的数字随机放进格子里,每个格子最多放一个。然后我们随机生成一个幸运行号 r (1≤r≤n)和幸运列号 c (1≤c≤m),再随机生成一个幸运六位数。中奖者是第 r 行和第 c 列的所有六位数中与幸运数最接近的那个数字的主人。

本题就请你写个程序实现这个抽奖功能。

输入格式:

输入第一行给出 2 个正整数 n 和 m(1≤n,m≤1000),随后 n 行,每行给出 m 个数字,对应该位置格子里玩家下注的数字。如果这个格子是空的,就用 −1 表示。最后一行给出幸运行号 r、幸运列号 c 和幸运六位数。同行数字间以空格分隔。

注意:行号从上向下递增,列号从左向右递增,均从 1 开始计数。

输出格式:

按照 (行号:列号) 的格式输出中奖者的位置。如果中奖者不唯一,则按照首先在幸运行中从左到右,然后在幸运列中从上到下的顺序输出,每行输出一位中奖者的位置。注意同一个位置只能输出一次。题目保证至少存在一位中奖者。

输入样例:

4 5
233333 000001 -1 888888 666666
001010 369624 777888 -1 999999
480735 100000 591846 369623 123123
456456 591846 000000 501000 233333
2 3 480735

输出样例:

(2:2)
(3:3)

7-8 521序列

题解

#include<bits/stdc++.h>
using namespace std;
int n, a[100010];
multiset<int> rec;
deque<int> ans;
map<int, int> cnt;
int main(){
    cin>>n;
    for(int i = 0; i < n; i ++){
        scanf("%d", &a[i]);
        cnt[a[i]]++;
    }
    for(auto i : cnt){
    	int tar = i.first;
        while(cnt[tar]){
            if(cnt[tar * 2] && cnt[tar * 5]){
                rec.insert(tar);
                cnt[tar]--;
                cnt[tar * 2]--;
                cnt[tar * 5]--;
            }else break;
        }
    }
    for(auto i : rec) ans.push_front(i);
    for(int i = 0; i < ans.size(); i ++){
        printf("%d", ans[i]);
        if(i != ans.size() - 1) printf(" ");
    }
    return 0;
}

题目

521.jpg

所谓“521 序列”是指将一个原始整数序列 S 中的每个数字分别乘以 5、2、1 后形成的序列,例如 S= { 5, 2, 1 } 时,其对应的 521 序列就是 { 25, 10, 5, 10, 4, 2, 5, 2, 1 } —— 这里我们不要求这个序列一定具有某种顺序,即 521 序列中元素的顺序是可以打乱的。给定 S 后,计算其对应的 521 序列是很简单的。但给定一个 521 序列,恢复其对应的原始序列 S 就略微复杂一点了。本题就请你恢复任意给定的 521 序列的原始序列。

输入格式:

输入第一行给出正整数 N(<105),为 521 序列的长度。随后一行给出 N 个整数,即给定的 521 序列。所有数字的绝对值不超过 105,以空格分隔。

输出格式:

在一行中按照非递增序输出 521 序列对应的原始序列。数字间以 1 个空格分隔,行首尾不得有多余空格。

题目保证原始序列是存在的。

输入样例:

12
1 -5 10 -1 2 4 5 -2 5 25 10 2

输出样例:

5 2 1 -1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值