PAT (Advanced Level) Practice

本文介绍了PAT高级水平的练习题,包括计算整数和的标准格式,多项式相加,以及紧急救援路径规划。在多项式相加中,使用map存储系数,从高位到低位输出。在紧急救援问题中,寻找最短路径并最大化救援团队数量。

#PAT (Advanced Level) Practice

Time:2021.5.15 

1001 A+B Format

Calculate a+b and output the sum in standard format – that is, the digits must be separated into groups of three by commas (unless there are less than four digits).
Input Specification:
Each input file contains one test case. Each case contains a pair of integers a and b where − 1 0 6 10^6 106≤a,b≤ 1 0 6 10^6 106.The numbers are separated by a space.
Output Specification:
For each test case, you should output the sum of a and b in one line. The sum must be written in the standard format.

Sample Input:

-1000000 9

Sample Output:

-999,991

// 1001

#include<iostream>
#include<vector>
using namespace std;

int main(){
    int a,b;
    int sum;
    cin>>a>>b;
    sum = a + b;

    if(sum == 0){
        cout<<0; //输出int型

    }

    if(sum < 0){
        cout<<"-";
        sum *= -1;
    }
    //-9997
    vector<int> v;
    while(sum != 0){
        v.emplace_back(sum%10); //7999
        sum /= 10;


    }
    //9,997从高位输入 9
    for(int i = v.size()-1; i>=0; i--){
        cout<<v[i];
        if(i>0 && i%3 == 0 ) cout<<","; // 大于零是为了不输出最前面的0
        //3 不是2是因为 先输出,比如第一个9 他是7999第四位,但是它坐标试3(坐标从0开始)
    }

    return 0;
}

1002 A+B for Polynomials

This time, you are supposed to find A+B where A and B are two polynomials.
Input Specification:
Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial:
在这里插入图片描述
where K is the number of nonzero terms in the polynomial, N ​ i ​_i i and aN ​ i ​_i i (i=1,2,⋯,K) are the exponents and coefficients, respectively. It is given that 1≤K≤10,0≤N K _K K<⋯<N 2 _2 2< N 1 N_1 N1≤1000.
Output Specification:
For each test case you should output the sum of A and B in one line, with the same format as the input. Notice that there must be NO extra space at the end of each line. Please be accurate to 1 decimal place.

Sample Input:

2 1 2.4 0 3.2
2 2 1.5 1 0.5

Sample Output:

3 2 1.5 1 2.9 0 3.2
  • 思路
    用double数组存xishu[1001]存系数,然后两次输入,系数为0的不输出,只输出不为零的位 和系数

  • 代码

# include <iostream>
# include <cstdio> //用到c语言printf输出
using namespace std;

int main(){
    int k;
    double xishu[1001]={0};
    
    // 两次输入 输入形式一样
    cin>>k;
    while(k--){
        int n;
        double d;
        
        cin>>n>>d;
        xishu[n] += d;        
    }
        cin>>k;
    while(k--){
        int n;
        double d;
        
        cin>>n>>d;
        xishu[n] += d;    
    } 	
	// 非零系数的数量,统计和输出
    int sum = 0;
    for(int i=0; i<=1000;i++){
        if(xishu[i] != 0){
            sum ++;
        }
    }
    cout<<sum;
    
    //输出非零系数的位数和系数
     for(int i = 1000;i>=0; i--){
       if(xishu[i] != 0)
                 printf(" %d %.1f", i, xishu[i]);
        }
    return 0;
}
  • 缺点:
    有可能会出现大量是0的系数,但我们每次都要不停的遍历。

  • 改进:

# include <iostream>
# include<map>
# include <cstdio>
using namespace std;

int main(){
    int k;
//     double xishu[1001]={0};
    map<int,double> xishu; //map本来就是空的,有的加上去
    
    cin>>k;
    while(k--){
        int n;
        double d;
        
        cin>>n>>d;
        xishu[n] += d;        
    }
        cin>>k;
    while(k--){
        int n;
        double d;
        
        cin>>n>>d;
        xishu[n] += d;
         //系数消去的话,把多项式消除掉
        if(xishu[n] == 0) xishu.erase(n);
    } 
    

    cout<<xishu.size();
    for(auto it= xishu.end();it!=xishu.begin();){
        --it;
        printf(" %d %.1f", it->first, it->second);
        }
    return 0;
}
  • 知识点1
# 1

 map<int,double> xishu; //map本来就是空的,有的加上去

(1)声明map容器xishu; 需要用到头部文件include < map > .
在这里插入图片描述
(2)map的功能
.
自动建立key - value的对应。key 和 value可以是任意你需要的类型,包括自定义类型。
.
(3) map<int,double> xishu;
这样就定义了一个用int作为索引,并拥有相关联的指向double的指针.
.
(4) map的基本操作函数 : 补充材料

  • erase() 删除一个元素

  • end() 返回指向map末尾的迭代器

  • begin() 返回指向map头部的迭代器

  • size() 返回map中元素的个数

     clear()        删除所有元素
    
     count()         返回指定元素出现的次数, (帮助评论区理解: 因为key值不会重复,所以只能是1 or 0)
    
     empty()         如果map为空则返回true
    
     end()           返回指向map末尾的迭代器
    
     equal_range()   返回特殊条目的迭代器对
    
     erase()         删除一个元素
    
     find()          查找一个元素
    
     get_allocator() 返回map的配置器
    
     insert()        插入元素
    
     key_comp()      返回比较元素key的函数
    
     lower_bound()   返回键值>=给定元素的第一个位置
    
     max_size()      返回可以容纳的最大元素个数
    
     rbegin()        返回一个指向map尾部的逆向迭代器
    
     rend()          返回一个指向map头部的逆向迭代器
    
     size()          返回map中元素的个数
    
     swap()           交换两个map
    
     upper_bound()    返回键值>给定元素的第一个位置
    
     value_comp()     返回比较元素value的函数
    
  • 知识点2
#  2

    for(auto it= xishu.end();it!=xishu.begin();){
        --it;
        printf(" %d %.1f", it->first, it->second);
        }

for(auto it= xishu.end();it!=xishu.begin(); )

https://blog.csdn.net/yexiaohhjk/article/details/103746838?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-1&spm=1001.2101.3001.4242链接

C++容器.map

https://www.bilibili.com/video/BV1oK411G7wP?from=search&seid=7365832764417704629

我们输入是高位往低位,输出也是高位到地位。 map天生有序,这时候咱们x的系数 就是i也就是map容器的key,所以高位先输出,那么就要从高位xishu.end()开始,到开始结束。用递减

printf(" %d %.1f", it->first, it->second);

first会得到Map中key的有效值,
second会得到Map中value的有效值。

  • 知识点3
if(xishu[n] == 0) xishu.erase(n);

我们如果两个多项式某一项同时存在,但相加为0;
这时候迭代器里面是有这个key的,但是value是0,所以要把这个删去;

补充:当迭代器没有哪一项,你要输出这项,返回时NULL
如果没有的一项 给它叠加,那么系统会自动添加这项,并把value=0,叠加后=叠加后的值。


1003 Emergency

As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.
Input Specification:
Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (≤500) - the number of cities (and the cities are numbered from 0 to N−1), M - the number of roads, C​1​​ and C​2 the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c​1 , c2 and Li, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C1 to C​2​​ .
Output Specification:
For each test case, print in one line two numbers: the number of different shortest paths between C​1 and C2, and the maximum amount of rescue teams you can possibly gather. All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.

Sample Input:

5 6 0 2
1 2 1 5 3
0 1 1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1

Sample Output:

2 4
  • 题目解析
    第一排输入 城市数5 道路数6 起点0 终点2
    第二排 每个城市救援人数(5个)
    后面几排 前两个是哪两个城市有路 路程多少(6个)

  • 题目思路
    ① if:如果到达一个城市,比前面一些道路到的用距离长,那么舍掉;
    ②else:如果到达城市是终点,距离数一样,那么最短路径的线路数+1,然后看看谁的人数多,多的保留;如果新路线里程少,那么保留新里程路线,人数。
    ③如果到达城市不是终点,里程近的更新最短路径,并且在这个新城市遍历相邻城市路线

  • 代码

#include<iostream>
#include<vector> //放距离
using namespace std;

int N,M,C1,C2;//city road
int num_of_team[501]; //人数
int dis[501][501]; //记录两点之间距离
int minDis[501]; //到某城市最短步数
int num_min_paths,team; //最短路个数,最多的人数

vector<int> v[500]; // 表示邻居有哪些

void dfs(int curCity, int curLen, int curTeam) // 当前城市,来到这个城市距离,来到这个城市时人数
{
    // 如果来到这城市 它当前所需距离要大于以前来过时的,那么不用再走了,删掉。
    if(curLen  > minDis[curCity]) return;
    
    //esle:curLen  <= minDis[curCity]
        //如果到达终点
    if(curCity == C2){
            //这时候如果距离都是最小距离,数量+1
            if(curLen  == minDis[curCity]){
                num_min_paths++;
                if(curTeam > team) team = curTeam;

            }
            //当前步伐小于最小步伐
            else{
                minDis[C2]=curLen;
                num_min_paths = 1; //这个最短距离就这一个
                team = curTeam;
            }

        }

        // 没到终点且不舍弃
     else{
            
            //如果比以前走的更短,更新到这个city的最短距离
            if(curLen  < minDis[curCity]) minDis[curCity]=curLen;
            
            for(int i=0;i<v[curCity].size();i++)
                {int j = v[curCity][i]; //新城市
                dfs(j,curLen+dis[curCity][j],curTeam+num_of_team[j]);
            }
        }


    }





int main(){

    int i,j,k,l;
    cin>>N>>M>>C1>>C2;

    // 存入每个城市救援人数量
    for(i=0;i<N;i++) cin>>num_of_team[i];
    for(i=0;i<M;i++){
        cin>>j>>k>>l; // j,k之间距离为l
        
        // 让j,k的邻居里加上k,j
        v[j].emplace_back(k);
        v[k].emplace_back(j);
        
        dis[j][k]=dis[k][j]=l; //距离数组
    }
  
    // 这里我们要注意 不能写成minDis[501]={10000000} 这个只是把第一minDis[0]改成了1000000
    //可以for(int i=0; i<501; i++) minDis[i]=10000000;全部初始化,但没必要
    for(int i=0; i<N; i++) minDis[i]=10000000;
    dfs(C1,0,num_of_team[C1]);
    cout<<num_min_paths<<" "<<team;
    
    return 0;


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

羊老羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值