首页 PAT-Raffle for Weibo Followers & Shortest Distance & A+B and C (64bit)
文章
取消

PAT-Raffle for Weibo Followers & Shortest Distance & A+B and C (64bit)

A1124. Raffle for Weibo Followers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<iostream>
#include<unordered_map>
using namespace std;
int main()
{
    int M,N,S;//M:粉丝人数,N:中奖人数间隔, S:开始的人序号(从1开始)
    cin>>M>>N>>S;
    if(S > M) cout<<"Keep going...";//开始序号大于粉丝数
    else
    {
        unordered_map<string, int> m;//用来查重
        string names[M + 1];
        //将名字放在数组中
        for(int i = 1; i <= M; i++)cin>>names[i];
        //开始抽奖
        int index = S;
        m[names[S]]++;//加入map
        cout<<names[S];
        index += N;
        while(index <= M)
        {
            if(m.count(names[index]))//如果已经中过奖
            {
                index++;
            }
            else//如果没中过奖
            {
                m[names[index]]++;//加入map
                cout<<endl<<names[index];
                index += N;
            }
        }

    }
}

    这道题太折磨了,本来挺简单的题,让我玩复杂了。我一开始为了省这一千个数组的空间复杂度,想挨个遍历,结果就问题重重,用取余来算,还有特判,最后只拿了17分(满分20),最后一个样例没通过,后来又改,结果改的四不像。最后还是选择了最简单的思路拿最多的分。这道题给我的教训是,拿分就行了,别老搁那想优化了嗷,优化半天代码量蹭蹭往上涨,bug也蹭蹭涨,就省那么点空间复杂度,真不值。

    PAT全英文+大量description,多少有点折磨了,但还是得适应,想念leetcode的第2天。

A1046. Shortest Distance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<iostream>
#include<cmath>
#include<vector>
using namespace std;

int main()
{
    //数据读入
    int N, M;//N:节点个数, M:询问次数
    cin>>N;
    //将每个节点的举例储存在数组中
    vector<int> dis(N + 1);//因为要从1开始,所以多申请一个空间
    for(int i = 1; i <= N; i++)
    {
        cin>>dis[i];
    }
    //储存前缀和
    vector<int> pre(N + 1);
    int sum = 0;
    pre[0] = dis[N];//0节点就储存从最后一个节点走到开头的距离
    //计算前缀和,计算从1节点到该位置需要走的距离
    for(int i = 1; i <= N; i++)
    {
        pre[i] = sum;
        sum += dis[i];
    }
    //开始处理询问
    cin>>M;
    while(M--)
    {
        int x,y;//储存两个位置
        cin>>x>>y;//读入
        //计算最短距离,两种情况,要么直达,要么反向直达
        int minIndex = min(x, y);//获取小坐标
        int maxIndex = max(x, y);//获取大坐标
        if(M != 0)//没处理到最后一个,都输出换行
        {
            //pre[maxIndex] - pre[minIndex] = 正向直达,从小坐标直接走到大坐标
            //pre[N] - pre[maxIndex] + pre[minIndex] + pre[0] = 反向直达
            //先从大坐标走到结尾,再从结尾走到小坐标
            //二者取小值打印
            cout<<min(pre[maxIndex] - pre[minIndex], pre[N] - pre[maxIndex] + pre[minIndex] + pre[0]);
            cout<<endl;
        }
        else//处理到最后一个, 不输出换行
        {
            cout<<min(pre[maxIndex] - pre[minIndex], pre[N] - pre[maxIndex] + pre[minIndex] + pre[0]);
        }
    }
}

    这道题是典型的前缀和,没什么多说的,需要注意的就是前缀和算哪一部分,包不包含自己节点,还有就是边界处理。

    由于PAT的题需要写头文件,所以经常会因为漏写头文件而导致编译错误,还要继续适应。

A1065. A+B and C (64bit)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    int N;//记录有几组数据
    scanf("%d", &N);
    for(int i = 1; i <= N; i++)
    {
        long long a,b,c;
        bool flag;
        scanf("%lld %lld %lld", &a, &b, &c);
        long long sum = a + b;//求和
        //判断溢出情况:
        //正溢出,肯定大于c
        if(a > 0 && b > 0 && sum <= 0)flag = true;
        //负溢出,肯定小于c
        else if(a < 0 && b < 0 && sum >= 0)flag = false;
        //正常情况
        else flag = sum > c;
        if(flag)//
        {
            //cout<<"Case #"<<i<<": "<<"true"<<endl;
            printf("Case #%d: true\n", i);
        }
        else printf("Case #%d: false\n", i);
            //cout<<"Case #"<<i<<": "<<"false"<<endl;
    }
}

    这道题,我起初想用字符串的运算,但好麻烦,看了别人的,直接算,去判断是否溢出就行了。而且有一件十分诡异的事情,就是,同样的代码,使用cin和cout的话,最后一个测试点就无法通过,但使用printf和scanf的话,就能通过,而且错误不是超时,是答案错误。

    这道题再次给我的教训就是,能暴力模拟就别想着花里胡哨。

本文由作者按照 CC BY 4.0 进行授权