PAT(甲级)2019年秋季考试

 

7-1 Forever (20 分)

做了这么多模拟题,我发现最难的还得是第一题。

注意点:1、暴力法超时,用回溯剪枝。2公因数有个条件是质数

#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
#include<cmath>
using namespace std;
int N, k, m;
using LL = long long;
int gcd(int x, int y){
    if(y==0) return x;
    return gcd(y, x%y);
}
bool is_prime(int x){
    int t = sqrt(x);
    for(int i = 2; i <= t; i++)
        if(x%i==0) return false;
    return true;
}
int handle(int x){
    int ans = 0;
    while(x!=0) {
        ans += x%10;
        x /= 10;
    }
    return ans;
}
int power(int k){
    int ans = 1;
    while(k--) ans *= 10;
    return ans;
}
map<int, vector<int>> ans;
void dfs(int tmp, int p, int sum){
    if(sum + (k-p)*9 < m) return;
    if(k==p) {
        if(sum!=m) return;
        int n = handle(tmp+1);
        if(sum < n) swap(sum, n);
        int z = gcd(sum, n);
        if(z>2 && is_prime(z)) ans[n].push_back(tmp);
        return;
    }
    for(int t = 0; t <= 9; t++){
        dfs(tmp*10+t, p+1, sum+t);
    }
}


int main(){
    scanf("%d", &N);
    for(int i = 0; i < N; i++){
        scanf("%d %d", &k, &m);
        ans.clear();
        dfs(0, 0, 0);
        
        printf("Case %d\n", i+1);
        for(auto a:ans){
            int t = a.first;
            sort(a.second.begin(), a.second.end());
            for(int i = 0; i < a.second.size(); i++){
                printf("%d %d\n", t, a.second[i]);
            }
        }
        if(ans.empty()) 
            printf("No Solution\n");
    }
}

7-2 Merging Linked Lists (25 分)

链表

#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
using namespace std;
int h1, h2; int N;
unordered_map<int, int> l;
vector<int> l1, l2;
unordered_map<int, int> val;
vector<int> ans;
void handle(vector<int>& v1, vector<int>& v2){
    int n1 = v1.size(), n2 = v2.size();
    reverse(v2.begin(), v2.end());
    int p = 0;
    while(true){
        if(2*p >= n1) break;
        if(2*p < n1) ans.push_back(v1[2*p]);
        if(2*p+1 < n1) ans.push_back(v1[2*p+1]);
        if(p < n2) ans.push_back(v2[p]);
        p++;
    }
}

int main(){
    scanf("%d %d %d", &h1, &h2, &N);
    for(int i = 0; i < N; i++){
        int x, y, z;
        scanf("%d %d %d", &x, &y, &z);
        l[x] = z; val[x] = y;
    }
    int cnt1 = 0; int cnt2 = 0;
    int t = h1; 
    while(t!=-1) {
        l1.push_back(t); t = l[t];
    }
    t = h2;
    while(t!=-1){
        l2.push_back(t); t = l[t];
    }
    if(l1.size() >= 2*l2.size()) handle(l1, l2);
    else  handle(l2, l1);
    for(int i = 0; i < ans.size(); i++){
        int t = ans[i];
        printf("%05d %d ", t, val[t]);
        if(i==ans.size()-1) printf("-1\n");
        else printf("%05d\n", ans[i+1]);
    }
    
}

7-3 Postfix Expression (25 分)

递归

#include<iostream>
#include<vector>
using namespace std;
int n;
struct Node{
    string s;
    int l, r;
    Node(string s, int l, int r):s(s), l(l), r(r){}
};
vector<Node*> v;

string handle(int x){
    string ans;
    if(x<0) return ans;
    string l = handle(v[x]->l); string r = handle(v[x]->r);
    if(l.empty()) ans = "("+v[x]->s+r+")";
    else ans = "("+l+r+v[x]->s+")";
    return ans;
}

int main(){
    scanf("%d", &n);
    vector<int> flags(n, 0);
    for(int i = 0; i < n; i++){
        string s; int l, r;
        cin >> s; scanf("%d %d", &l, &r);
        if(l!=-1) flags[l-1] = 1;
        if(r!=-1) flags[r-1] = 1;
        Node *p = new Node(s, l-1, r-1);
        v.push_back(p);
    }
    int h = -1;
    for(int i = 0; i < n; i++) 
        if(flags[i]==0) {h = i; break;}
    string ans = handle(h);
    cout << ans << endl;
    
}

7-4 Dijkstra Sequence (30 分)

#include<iostream>
#include<vector>
using namespace std;
int n, m, k;
vector<vector<int>> grid;

int main(){
    scanf("%d %d", &n, &m);
    grid.resize(n+1, vector<int>(n+1, -1));
    for(int i = 0; i < m; i++){
        int x, y, z;
        scanf("%d %d %d", &x, &y, &z);
        grid[x][y] = grid[y][x] = z;
    }
    scanf("%d", &k);
    for(int i = 0; i < k; i++){
        vector<int> order;
        for(int j = 0; j < n; j++){
            int x; scanf("%d", &x);
            order.push_back(x);
        }
        int p = order[0];
        vector<int> dis = grid[p];
        dis[p] = 0;
        vector<int> visited(n+1, 0);
        bool ok = true;
        for(int t = 0; t < n; t++){
            int id = -1; int M = 1e9;
            for(int l = 1; l <= n; l++){
                if(dis[l]!=-1 && dis[l] < M && visited[l]==0) {
                    id = l; M = dis[l];
                }
            }
            if(dis[order[t]]!=M) {ok = false; break;}
            id = order[t]; visited[id] = 1;
            for(int l = 1; l <= n; l++){
                if(visited[l]==1 || grid[id][l]==-1) continue;
                if(dis[l]==-1 || dis[l] > dis[id]+grid[id][l]) dis[l] = dis[id]+grid[id][l];
            }
        }
        if(ok) printf("Yes\n");
        else printf("No\n");
    }
    
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值