PAT (Advanced Level) 1132~1135:1132 模拟 1133模拟(易超时!) 1134图 1135红黑树

1132 Cut Integer(20 分)

题意:将一个含K(K为偶数)个数字的整数Z割分为A和B两部分,若Z能被A*B整除,则输出Yes,否则输出No。

分析:当A*B为0的时候,不能被Z整除,输出No。否则会出现浮点错误。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<map>
#include<iostream>
#include<vector>
#include<set>
#include<cmath>
using namespace std;
char s[20];
int main(){
    int N;
    scanf("%d", &N);
    while(N--){
        scanf("%s", s);
        int len = strlen(s);
        int A = 0;
        for(int i = 0; i < len / 2; ++i){
            A = A * 10 + s[i] - '0';
        }
        int B = 0;
        for(int i = len / 2; i < len; ++i){
            B = B * 10 + s[i] - '0';
        }
        int C = A * B;
        if(C == 0){
            printf("No\n");
            continue;
        }
        int x = atoi(s);
        if(x % C == 0) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

1133 Splitting A Linked List(25 分)

题意:给定一个链表,将链表重新排序,在不打乱原链表相对顺序的前提下,小于0的在最前面,其次是0~K,最后是大于K的数。

分析:

1、3次遍历可实现链表重排。

2、map映射value和pre或suc的关系会超时,所以,以pre为结点定义结构体,组织链表的重排,从而进行优化。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<map>
#include<iostream>
#include<vector>
#include<set>
#include<cmath>
using namespace std;
const int MAXN = 100000 + 10;
struct Node{
    int pre, value, suc;
}num[MAXN];
vector<int> old, ans;
int main(){
    int N, K, head, pre, value, suc;
    scanf("%d%d%d", &head, &N, &K);
    for(int i = 0; i < N; ++i){
        scanf("%d%d%d", &pre, &value, &suc);
        num[pre].pre = pre;
        num[pre].value = value;
        num[pre].suc = suc;
    }
    while(head != -1){
        old.push_back(head);
        head = num[head].suc;
    }
    int len = old.size();
    for(int i = 0; i < len; ++i){
        if(num[old[i]].value < 0) ans.push_back(old[i]);
    }
    for(int i = 0; i < len; ++i){
        if(num[old[i]].value >= 0 && num[old[i]].value <= K) ans.push_back(old[i]);
    }
    for(int i = 0; i < len; ++i){
        if(num[old[i]].value > K) ans.push_back(old[i]);
    }
    for(int i = 0; i < len - 1; ++i){
        printf("%05d %d %05d\n", ans[i], num[ans[i]].value, ans[i + 1]);
    }
    printf("%05d %d -1\n", ans[len - 1], num[ans[len - 1]].value);
    return 0;
}
1134 Vertex Cover(25 分)

题意:vertex cover是指图中一些点的集合,使得图中每一条边的两个点中都至少有一个点在该点集中。给定点的集合,判断是否为vertex cover。

分析:按题意模拟即可。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<map>
#include<iostream>
#include<vector>
#include<set>
#include<cmath>
using namespace std;
const int MAXN = 10000 + 10;
int N, M;
bool vis[MAXN];
struct Edge{
    int u, v;
    void read(){
        scanf("%d%d", &u, &v);
    }
}num[MAXN];
int main(){
    scanf("%d%d", &N, &M);
    for(int i = 0; i < M; ++i){
        num[i].read();
    }
    int K;
    scanf("%d", &K);
    while(K--){
        int n, x;
        scanf("%d", &n);
        memset(vis, false, sizeof vis);
        while(n--){
            scanf("%d", &x);
            vis[x] = true;
        }
        bool ok = true;
        for(int i = 0; i < M; ++i){
            if(vis[num[i].u] || vis[num[i].v]) continue;
            ok = false;
            break;
        }
        if(ok) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

1135 Is It A Red-Black Tree(30 分

题意:给定一棵二叉搜索树的前序遍历序列,判断其是否为一棵红黑树。

分析:

1、红黑树是一棵平衡的二叉搜索树,满足以下条件:

(1)所有结点不是红色就是黑色;

(2)根结点是黑色;

(3)每一个为NULL的叶子结点是黑色;

(4)如果某结点是红色,其左右子结点都是黑色;

(5)对于每个结点,其到所有后代叶子结点经过的黑色结点数相同;

2、根据给定的前序遍历序列,结合二叉搜索树的定义可以建树。

3、递归检查条件4。

4、同理,递归统计左右子树的黑色结点数,来检查条件5。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<map>
#include<iostream>
#include<vector>
#include<set>
#include<cmath>
using namespace std;
const int MAXN = 30 + 10;
struct Node{
    Node *left, *right;
    int value;
};
struct Node *root;
bool ok;
void build(Node* &r, int x){
    if(r == NULL){
        r = (Node*)malloc(sizeof(Node));
        r -> value = x;
        r -> left = r -> right = NULL;
        return;
    }
    if(abs(x) < abs(r -> value)){
        build(r -> left, x);
    }
    else{
        build(r -> right, x);
    }
}
void judge_RedNode(Node* r){
    if(!ok) return;
    if(r -> left != NULL){
        if(r -> value < 0 && r -> left -> value < 0){
            ok = false;
            return;
        }
        else judge_RedNode(r -> left);
    }
    if(r -> right != NULL){
        if(r -> value < 0 && r -> right -> value < 0){
            ok = false;
            return;
        }
        else judge_RedNode(r -> right);
    }
}
int judge_BlackNode(Node* r){
    int leftcnt, rightcnt;
    if(!ok) return -1;
    if(r == NULL) return 1;
    leftcnt = judge_BlackNode(r -> left);
    rightcnt = judge_BlackNode(r -> right);
    if(leftcnt != rightcnt){
        ok = false;
        return -1;
    }
    else{
        if(r -> value > 0) ++leftcnt;
    }
    return leftcnt;
}
int main(){
    int K;
    scanf("%d", &K);
    while(K--){
        root = NULL;
        int N, x;
        scanf("%d", &N);
        while(N--){
            scanf("%d", &x);
            build(root, x);
        }
        ok = true;
        judge_RedNode(root);
        judge_BlackNode(root);
        if(root -> value < 0 || !ok){
            printf("No\n");
        }
        else{
            printf("Yes\n");
        }
    }
    return 0;
}

  

转载于:https://www.cnblogs.com/tyty-Somnuspoppy/p/9560759.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值