2021.9PAT备考刷题笔记(30分题我唯唯诺诺,20分题我重拳出击)

1001 考察点 字符串的处理

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

int main(){
    int x, y;
    cin >> x >> y;
    string s = to_string(x+y);
    for(int i = 0; i < s.size(); i++){
        printf("%c", s[i]);
        if(s[i]=='-') continue;
        int t = s.size()-i-1;
        if(t%3==0 && t!=0) printf(",");
    }
    printf("\n");
}

1002 思路:开个一百的数组,记录每一项的系数。最后数下几个非零项,依次输出

#include<iostream>
#include<vector>
using namespace std;
const int M = 1000+3;

int main(){
    vector<double> v(M, 0);
    int K; 
    scanf("%d", &K);
    for(int i = 0; i < K; i++){
        int x; double y;
        scanf("%d %lf", &x, &y);
        v[x] += y;
    }
    int cnt = 0;
    scanf("%d", &K);
    for(int i = 0; i < K; i++){
        int x; double y;
        scanf("%d %lf", &x, &y);
        v[x] += y;
    }
    for(int i = M-1; i >= 0; i--)
        if(v[i]!=0) cnt++;
    printf("%d", cnt);
    for(int i = M-1; i >= 0; i--){
        if(v[i] !=0 ) printf(" %d %.1f", i, v[i]);
    }
    printf("\n");
}

 1003 Dij那什么求最短路的算法。要新建两个变量保存路径条数和最大重量,更新最短路的时候分为大于和等于两种情况。

#include<iostream>
#include<vector>
#include<limits.h>
using namespace std;
int n, m, c1, c2;
vector<int> w;
vector<vector<int>> dis;
vector<int> visited;
vector<int> cnts;
vector<int> weights;
int main(){
    scanf("%d %d %d %d", &n, &m, &c1, &c2);
    for(int i = 0; i < n; i++){
        int x; scanf("%d", &x);
        w.push_back(x);
    }
    dis.resize(n, vector<int>(n, -1));
    for(int i = 0; i < m; i++){
        int x, y, d; scanf("%d %d %d", &x, &y, &d);
        dis[x][y] = dis[y][x] = d;
    }
    dis[c1][c1] = 0;
    visited.resize(n, 0);
    //visited[c1] = 1;
    cnts.resize(n, 0); cnts[c1] = 1;
    weights.resize(n, 0); weights[c1] = w[c1];
    for(int i = 0; i < n; i++){
        int M = INT_MAX;
        int t = -1;
        for(int j = 0; j < n; j++){
            if(visited[j]==0 && dis[c1][j]!=-1 && dis[c1][j]<M){
                M = dis[c1][j];
                t = j;
            }
        }
        visited[t] = 1;
        for(int j = 0; j < n; j++){
            if(visited[j]==0 && dis[t][j]!=-1){
                if(dis[c1][j]==-1 || dis[c1][j]>dis[c1][t]+dis[t][j]){
                    dis[c1][j] = dis[c1][t]+dis[t][j];
                    cnts[j] = cnts[t];
                    weights[j] = weights[t]+w[j];
                }
                else if(dis[c1][j]==dis[c1][t]+dis[t][j]){
                    cnts[j] += cnts[t];
                    weights[j] = max(weights[j], weights[t]+w[j]);
                }
            }
        }
    }
    printf("%d %d\n", cnts[c2], weights[c2]);
    //cout << cnts[c2] << " ;
}

1004 bfs

#include <iostream>
#include <vector>
#include<queue>
#include<unordered_map>
using namespace std;
const int MAX = 100+2;
int N, M;

int main(){
    scanf("%d %d", &N, &M);
    vector<vector<int>> tree(MAX);
    for(int i = 0; i < M; i++){
        int id, k;
        scanf("%d %d", &id, &k);
        for(int j = 0; j < k; j++){
            int x; scanf("%d", &x);
            tree[id].push_back(x);
        }
    }
    int root = 1;
    queue<int> q;
    vector<int> cnt(MAX, 0);
    unordered_map<int, int> deep; 
    deep[1] = 0; q.push(1);
    int D = 0;
    while(!q.empty()){
        int t = q.front(); q.pop();
        D = deep[t];
        if(tree[t].empty()) cnt[deep[t]]++;
        for(int i = 0; i < tree[t].size(); i++){
            int y = tree[t][i];
            deep[y] = deep[t]+1;
            q.push(y);
        }
    }
    bool first = true;
    for(int i = 0; i <= D; i++)
    {
        if(first) first = false; else printf(" ");
        printf("%d", cnt[i]);
    }
    printf("\n");
    
    
}

 1005 注意和直接为零的情况。WA了一个测试点。

#include<iostream>
#include<vector>
using namespace std;
vector<string> v = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
int main(){
    string s;
    cin >> s;
    int n = 0;
    for(int i = 0; i < s.size(); i++){
        n += s[i]-'0';
    }
    if(n==0) {
        cout << "zero" << endl;
        return 0;
    }
    bool first = true;
    vector<string> ans;
    while(n>0){
        //
        ans.push_back(v[n%10]);
        n = n/10;
    }
    for(int i = ans.size()-1; i>=0; i--){
        if(first) first = false; else printf(" ");
        cout << ans[i];
    }
    
    printf("\n");
}

 1006 就按题目说的做

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

int main(){
    scanf("%d", &m);
    vector<string> ids;
    //vector<int> arrs, leas;
    int A = 1e8, B = 0;
    int x = -1, y = -1;
    for(int i = 0; i < m; i++){
        string s; cin >> s;
        ids.push_back(s);
        int x1, y1, z1, x2, y2, z2;
        scanf("%d:%d:%d %d:%d:%d", &x1, &y1, &z1, &x2, &y2, &z2);
        //arrs.push_back(x1*3600+y1*60+z1);
        //leas.push_back(x2*3600+y2*60+z2);
        int a = x1*3600+y1*60+z1, b = x2*3600+y2*60+z2;
        if(a<A) {A = a; x = i;}
        if(b>B) {B = b; y = i;}
    }
    cout << ids[x] << " " << ids[y] << endl;
    
}

 1007 滑动窗口 保持窗口内和大于零,看情况更新答案。注意全负数的情况,还要注意和为零算普通的答案。

#include<iostream>
#include<vector>
using namespace std;
int m;
vector<int> v;
int main(){
    scanf("%d", &m);
    for(int i = 0; i < m; i++){
        int x; scanf("%d", &x);
        v.push_back(x);
    }
    int l = 0, r = 0;
    int sum = 0;
    int L = -1, R = -1, ans = -1;
    while(r < m){
        sum += v[r];
        if(sum < 0) {
            l = r+1;
            sum = 0;
        }
        else if(sum > ans){
            ans = sum;
            L = l; R = r;
            //cout << l << " " << r << " " << sum << endl;
        }
        r++;
    }
    if(ans == -1) printf("%d %d %d\n", 0, v[0], v[m-1]);
    else printf("%d %d %d\n", ans, v[L], v[R]);
}

1008 题面意思

#include<iostream>
#include<vector>
using namespace std;
int n;
vector<int> v;
int main(){
    scanf("%d", &n);
    for(int i = 0; i < n; i++){
        int x; scanf("%d", &x);
        v.push_back(x);
    }
    int ans = 0;
    for(int i = 0; i < n; i++){
        if(i==0) ans += v[i]*6;
        else {
            if(v[i] > v[i-1]) 
                ans += (v[i]-v[i-1])*6;
            else 
                ans += (v[i-1]-v[i])*4;
        }
        ans += 5;
    }
    printf("%d\n", ans);
    
}

1009 和上面那个多项式题目类似。哇照这个进度我一天能不能A十道啊。

#include<iostream>
#include<vector>
#include<unordered_map>
using namespace std;
const int M = 2000+5;
int k;

int main(){
    unordered_map<int, double> T1, T2;
    scanf("%d", &k);
    for(int i = 0; i < k; i++){
        int x; double y; 
        scanf("%d %lf", &x, &y);
        T1[x] = y;
    }
    scanf("%d", &k);
    for(int i = 0; i < k; i++){
        int x; double y;
        scanf("%d %lf", &x, &y);
        T2[x] = y;
    }
    vector<double> cos(M, 0);
    for(const auto& a:T1){
        for(const auto& b:T2){
            cos[a.first+b.first] += a.second*b.second;
        }
    }
    int cnt = 0;
    for(int i = 0; i < M; i++)
        if(cos[i]!=0) cnt++;
    printf("%d", cnt);
    for(int i = M-1; i >= 0; i--){
        if(cos[i]!=0) printf(" %d %.1f", i, cos[i]);
    }
    printf("\n");
}

1010 救命 WA了两次呜呜呜还没写出来待我看看。错误点1:进制选择没有上限,我自以为地设置为36。看了一圈题解要二分还要处理溢出orz明天再弄吧。但是为了一天A10题我决定苟个下一题。

气死俺了,这道题花了好长时间,考察的知识点主要是进制。1进制转换要把变量统一为long long。2如果不用二分法直接求,测试点7会超时,得24分,其实我觉得无伤大雅。3二分法我写的条件忘了加else,就这个卡了半天。4其实我没太整明白乘法的溢出的,但是就硬记吧。。

(ps:感谢柳大神

#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
using LL = long long;
string n1, n2;
long long tag, radix;
long long num1, num2;
long long convert(string n, long long radix){
    long long ans = 0;
    for(auto a:n){
        LL t = isdigit(a)?(a-'0'):(a-'a'+10);
        ans = ans*radix+t;
        if(ans < 0) return -1;
    }
    return ans;
}
long long handle(){
    LL l = 2;
    for(auto a:n2){
        long long x = isdigit(a)?(a-'0'):(a-'a'+10);
        l = max(l, x+1);
    }
    LL r = max(num1, l);
    while(l <= r){
        LL m = (l+r)/2;
        num2 = convert(n2, m);
        if(num2<0 || num2 > num1) r = m-1;
        else if(num2 == num1) return m;
        else if(num2 < num1) l = m+1;
    }
    return -1;
}


int main(){
    cin >> n1 >> n2 >> tag >> radix;
    if(tag==2) swap(n1, n2);
    num1 = 0; num2 = 0;
    num1 = convert(n1, radix);
    LL ans = handle();
    if(ans==-1) printf("Impossible\n");
    else printf("%lld\n", ans);
    
}

1011

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

int main(){
    double x;
    double ans = 1;
    vector<char> v = {'W', 'T', 'L'};
    for(int i = 0; i < 3; i++){
        x = 0; char t;
        for(int j = 0; j < 3; j++){
            double c; scanf("%lf", &c);
            if(c > x) t = v[j];
            x = max(x, c);
        }
        printf("%c ", t);
        ans *= x;
    }
    ans = (ans*0.65-1)*2;
    printf("%.2f\n", ans);
}

1012 救。。。这道题一直3,4测试点段错误,查了好久没看出错在哪orz。咋办呜呜呜。 

太迷惑了,,,调试了几下提交了几次也没查出哪里错,原封不动地重新交了一遍通过了???

真见鬼了我靠。就是先把每门功课都排列一次,更新每个人的最佳名次。好像可以结构化但是那种写法我不太熟练,后面的题目可以练一下。

#include<iostream>
#include<vector>
#include<algorithm>
#include<unordered_map>
using namespace std;
const int MAX = 1e6+5;
int n, m;
vector<int> names(MAX, -1);
vector<double> C, M, E, A;
vector<int> Rank;
vector<char> W;
void handle(char c, const vector<double>& v){
    vector<int> ids;
    for(int i = 0; i < n; i++) ids.push_back(i);
    sort(ids.begin(), ids.end(), [&](const int& l,const int& r){
        return v[l] > v[r];});
    //for(int i = 0; i < v.size(); i++) cout << v[i] << " "; cout << endl;
    vector<int> meiko(n, 1);
    for(int i = 0; i < n; i++){
        //cout << ids[i] << " ";
        if(i>0 && v[ids[i]]==v[ids[i-1]]) meiko[i] = meiko[i-1];
        else meiko[i] = i+1;
        if(Rank[ids[i]] > meiko[i]) {Rank[ids[i]] = meiko[i]; W[ids[i]] = c;}
    }
    //cout << endl;
}

int main(){
    scanf("%d %d", &n, &m);
    for(int i = 0; i < n; i++){
        int s; double c, m, e;
        cin >> s; scanf("%lf %lf %lf", &c, &m, &e);
        names[s] = i; C.push_back(c); M.push_back(m); E.push_back(e);
        A.push_back((c+m+e)/3);
        //cout << c << " " << m << " " << e << " " << endl;
    }
    Rank.resize(n,n+1);
    W.resize(n, 'A');
    
    handle('A', A);
    handle('C', C);
    handle('M', M);
    handle('E', E);
    
    for(int i = 0; i < m; i++){
        int s; cin >> s;
        if(names[s]==-1) {printf("N/A\n"); continue;}
        int id = names[s];
        //cout << s <<" ";
        printf("%d %c\n", Rank[id], W[id]);
        
    }
    
}

1013 并查集或者dfs。tips:写并查集是时候用unordered_map记录父节点最后一个测试点超时了。

#include<iostream>
#include<vector>
#include<unordered_map>
#include<unordered_set>
#include<cstring>
using namespace std;
const int M = 1000+5;
int n, m, k;
vector<int> fathers(M, 0);
int find_father(int n){
    if(fathers[n]==n){
        return n;
    }
    fathers[n] = find_father(fathers[n]);
    return fathers[n];
}
void bind(int x, int y){
    int u = find_father(x);
    int v = find_father(y);
    fathers[u] = v;
}

int main(){
    scanf("%d %d %d", &n, &m, &k);
    vector<vector<int>> lines;
    for(int i = 0; i < m; i++){
        int x, y; scanf("%d %d", &x, &y);
        lines.push_back({x, y});
    }
    for(int i = 0; i < k; i++){
        int t; scanf("%d", &t);
        for(int j = 0; j <= n; j++) fathers[j] = j;
        for(int j = 0; j < m; j++){
            if(lines[j][0]==t || lines[j][1]==t) continue;
            bind(lines[j][0], lines[j][1]);
        }
        unordered_set<int> cnts;
        for(int j = 1; j <= n; j++){
            int r = find_father(j);
            cnts.insert(r);
        }
        int ans = cnts.size()-2;
        printf("%d\n", ans);
        
    }
}
#include<iostream>
#include<vector>
#include<unordered_map>
#include<unordered_set>
#include<cstring>
using namespace std;
const int M = 1000+5;
int n, m, k, x;
unordered_map<int, vector<int>> mp;
vector<int> flag;
void dfs(int t, int c){
    if(t==x || flag[t]!=0) return;
    flag[t] = c;
    if(mp.count(t)==0) return;
    for(int i = 0; i < mp[t].size(); i++){
        int x = mp[t][i];
        if(t!=x && flag[x]==0) dfs(x, c);
    }
}

int main(){
    scanf("%d %d %d", &n, &m, &k);
    
    for(int i = 0; i < m; i++){
        int x, y; scanf("%d %d", &x, &y);
        mp[x].push_back(y);
        mp[y].push_back(x);
    }
    flag.resize(n+1, 0);
    for(int i = 0; i < k; i++){
        scanf("%d", &x); int cnt = 1;
        for(int t = 0; t <= n; t++) flag[t] = 0;
        for(int j = 1; j <= n; j++){
            if(j!=x && flag[j]==0) dfs(j, cnt++);
        }
        printf("%d\n", cnt-2);
    }
    
}

1014 这种写结构体的模拟的题我不太会啊。就有点思路,但是捋不清楚。看下柳神的解析。

模拟的题目要选好结构化对象,本题是窗口。窗口的出列时间,结束时间,该窗口中的队列信息。感觉要熟练快速整合这种信息还是得练。顺便,柳姐,yyds。

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
int n, m, k, q;
struct Node{
    int poptime, endtime;
    queue<int> q;
};
vector<int> costs;
vector<Node*> windows;
vector<int> ans;

int main(){
    scanf("%d %d %d %d", &n, &m, &k, &q);
    for(int i = 0; i < k; i++){
        int x; scanf("%d", &x);
        costs.push_back(x);
    }
    int id = 0;
    ans.resize(k, 0);
    for(int j = 0; j < m; j++){
        for(int i = 0; i < n; i++){
            if(id >= k) break;
            if(j==0) {
                Node *p = new Node();
                p->poptime = costs[i]; p->endtime = 0;
                windows.push_back(p);
            }
            if(j!=0) windows[i]->q.push(costs[id]);
            windows[i]->endtime += costs[id];
            ans[id] = windows[i]->endtime;
            id++;
        }
    }
    
    ans.resize(k, 0);
    
    while(id < k){
        int T = 1e9; int t = -1;
        for(int i = 0; i < n; i++){
            if(windows[i]->poptime < T) {
                T = windows[i]->poptime;
                t = i;
            }
        }
        windows[t]->poptime += windows[t]->q.front();
        windows[t]->q.push(costs[id]);
        windows[t]->endtime += costs[id];
        ans[id] = windows[t]->endtime;
        //cout << id << " " << t << " " << windows[t]->poptime << " " << windows[t]->endtime << endl;
        id++;
    }
    
    for(int i = 0; i < q; i++){
        int x; scanf("%d", &x);
        int t = ans[x-1]; int w = t-costs[x-1];
        //cout << x << " " << t << " " << w << endl;
        if(w>=540) printf("Sorry\n");
        else printf("%02d:%02d\n", 8+t/60, t%60);
    }
    
    
}

1015 进制写法练习,判断质数

#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
int n, d;
bool judge(int n){
    if(n==0 || n==1) return false;
    int x = sqrt(n);
    for(int i = 2; i <= x; i++){
        if(n%i==0) return false;
    }
    return true;
}

int main(){
    while(scanf("%d", &n) == 1){
        if(n<0) break; scanf("%d", &d);
        bool ok1 = judge(n);
        int n1 = 0;
        while(n > 0){
            int x = n%d;
            n1 = n1*d+x;
            n = n/d;
        }
        bool ok2 = judge(n1);
        if(ok1 && ok2) printf("Yes\n");
        else printf("No\n");
        
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值