【算法】【PAT】1021-1030

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

1021 Deepest Root (25分) 推荐指数:3星

题目

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

5
1 2
1 3
1 4
2 5

Sample Output 1:

3
4
5

Sample Input 2:

5
1 3
1 4
2 5
3 4

Sample Output 2:

Error: 2 components

分析

推荐指数:3星

这道题的deepest root 输出的是根节点,并没有写错
输入是
1 2
1 3
1 4
2 5
最深的长度是 4
有 5-2-1-3 , 3-1-2-5, 4-1-2-5这三条路径和三个节点
if (i == 1) 假设必然经过1点,其实是对的,因为不少于1个,1是肯定会经过的点,如果还有则用作开头的点
sp是在i==1的情况下最深的点
把第一遍找最深的点集和第二遍从cp出发的点集的并,就是所有最深的点
实时更新最深的长度

要点

  • 利用了set集合的自动排序

题解

#include <iostream>
#include <vector>
#include <set>
#include <cstdio>
#include <algorithm>
using namespace std;
vector<int> e[10010], tmp;
int sp, maxDepth = 0;
bool visit[10010] = {
   false};
set<int> result;
void dfs(int node , int depth){
   
    visit[node] = true;
    if (depth > maxDepth){
   
        tmp.clear();
        tmp.push_back(node);
        maxDepth = depth;
    }else if (depth == maxDepth){
   
        tmp.push_back(node);
    }
    for(int i = 0; i<e[node].size(); i++){
   
        if(!visit[e[node][i]]) dfs(e[node][i], depth+1);
    }
}
int main(){
   
#ifndef ONLINE_JUDGE
    freopen("data.txt", "r", stdin);
#endif // ONLINE_JUDGE
    int n, a, b, k = 0;
    cin >> n;
    for (int i = 0 ; i < n-1; i++){
   
        scanf("%d %d", &a, &b);
        e[a].push_back(b);
        e[b].push_back(a);
    }
    for(int i = 1; i <= n; i++){
   
        if (!visit[i]){
   
            k++;
            dfs(i, 1);
            if (i == 1) sp = tmp[0]; ///过同一点(root)的最长叶子
        }
    }
    for (int i = 0; i < tmp.size(); i++){
   
        result.insert(tmp[i]); /// set过滤掉重合部分
    }
    tmp.clear();
    if (k > 1) printf("Error: %d components", k);
    else{
   
        fill(visit, visit+10010, false);
        dfs(sp,1);
        for(int i = 0; i < tmp.size(); i++) result.insert(tmp[i]); 
        for(auto it = result.begin(); it != result.end(); it++){
   
            printf("%d\n", *it);
        }
    }
    return 0;
}

1022 Digital Library (30分)

题目

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

3
1111111
The Testing Book
Yue Chen
test code debug sort keywords
ZUCS Print
2011
3333333
Another Testing Book
Yue Chen
test code sort keywords
ZUCS Print2
2012
2222222
The Testing Book
CYLL
keywords debug book
ZUCS Print2
2011
6
1: The Testing Book
2: Yue Chen
3: keywords
4: ZUCS Print
5: 2011
3: blablabla

Sample Output:

1: The Testing Book
1111111
2222222
2: Yue Chen
1111111
3333333
3: keywords
1111111
2222222
3333333
4: ZUCS Print
1111111
5: 2011
1111111
2222222
3: blablabla
Not Found

分析

模拟题+搜索+string处理

输入一整行数据的方法:
string a;
getline(cin, a);
输入带空格的整行的方法:
while(cin >> tkey){
key[tkey].insert[id];
char c = getchar();
if (c == ‘\n’) break; ///终止条件,很重要
}

要点

  • 在query的时候要注意使用 & 别名,不然会导致时间浪费(复制数据会导致比较大的开销
  • cin遇到空格 和 换行 都会停止输入,获取整行应该使用getline
  • 带排序的 —— 用set
  • 数据格式:07d

题解

#include <iostream>
#include <map>
#include <set>
using namespace std;
map<string, set<int> > title, author, key, pub, year; //使用map, 内存换时间
void query(map<string, set<int> > &m, string &str) {
    //检索map函数
    if(m.find(str) != m.end()) {
   
        for(auto it = m[str].begin(); it != m[str].end(); it++)
            printf("%07d\n", *it); //注意07d
    } else
        cout << "Not Found\n";
}
int main() {
   
    #ifndef ONLINE_JUDGE
    freopen("data.txt","r", stdin);
    #endif // ONLINE_JUDGE
    int n, m, id, num;
    scanf("%d", &n);
    string ttitle, tauthor, tkey, tpub, tyear; //
    for(int i = 0; i < n; i++) {
   
        scanf("%d\n", &id);    //获取id
        getline(cin, ttitle); //直接获取一整行
        title[ttitle].insert(id); //获取书名
        getline(cin, tauthor);
        author[tauthor].insert(id);
        while(cin >> tkey) {
    //直接输入, 直到遇到回车
            key[tkey].insert(id);
            char c = getchar(); ///获取下一个字符类型
            if(c == '\n') break; ///遇到回车,退出
        }
        getline(cin, tpub);
        pub[tpub].insert(id);
        getline(cin, tyear);
        year[tyear].insert(id);
    }
    scanf("%d", &m);
    for(int i = 0; i < m; i++) {
   
        scanf("%d: ", &num); //检索类型
        string temp;
        getline(cin, temp);
        cout 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值