2012年北邮计算机学院上机题目

Problem A. 二叉排序树
题目描述:
二叉排序树,也称二叉查找树。可以是一棵空树,也可以是一棵具有如下特性的非空二叉树:
1.若左子树非空,则左子树上所有节点关键字值均不大于根结点的关键字值;
2.若右子树非空,则右子树上所有节点关键字值均不小于根结点的关键字值;
3.左、右子树本身也是一棵二叉排序树。
现在给你N个关键字值各不相同的节点,要求你按顺序插入一个初始为空的二叉树中,每次插入成功后,求相应的父节点的关键字值,如果没有父节点,则输出-1。
输入:
输入包含多组测试数据,每组测试数据两行。
第一行,一个数字N(N<=100),表示待插入的节点数。
第二行,N个互不相同的正整数,表示要顺序插入节点的关键字值,这些值不超过10的8次方。
输出:
输出共N行,每次插入节点后,该节点对应的父节点的关键字值。
样例输入:
5
2 5 1 3 4
样例输出
-1
2
2
5
3
  思路:二叉树的基本操作,只不过这里是排序二叉树。

#include<stdio.h>
#include<string.h>

struct Node {
    Node *lchild;
    Node *rchild;
    int x;
}tree[100];

int alloc;

Node *create() {
    tree[alloc].lchild = tree[alloc].rchild = NULL;
    return &tree[alloc++]; 
}

Node *insert(Node *T,int x) {
    if(T == NULL) {
        T = create();
        T->x = x;
        return T;
    } else {
    if(T->x > x) {
            T->lchild = insert(T->lchild,x);
        } else {
            if(T->x < x) {
                T->rchild = insert(T->rchild,x);
            }
        }
    }
    return T;
}

void preOrder(Node *T,int t) {
    if(!T) {
        return;
    }
    if(T->lchild && T->lchild->x == t) {
        printf("%d\n",T->x);
        return;
    }
    if(T->rchild && T->rchild->x == t) {
        printf("%d\n",T->x);
        return;
    }
    preOrder(T->lchild,t);
    preOrder(T->rchild,t);
}

int main() {
    int N,a[100];
    while(scanf("%d",&N) != EOF) {
        scanf("%d",&a[0]);
        Node *T = insert(NULL,a[0]);
        int temp;
        for(int i = 1;i < N;i++) {
            scanf("%d",&a[i]);
            insert(T,a[i]);
        }
        printf("-1\n");
        for(int i = 1;i < N;i++) {
            preOrder(T,a[i]);
        }      
    }
}

Problem B. 二进制数
题目描述
大家都知道,数据在计算机中存储是以二进制的形式存储的。
有一天,小明学了C语言之后,他想知道一个类型为unsigned int 类型的数字,存储在计算机中的二进制串是什么样子的。
你能帮帮小明吗?并且,小明不想要二进制串中前面没有意义的0串,即要去掉前导0.
输入:
第一行,一个数字T(T<=1000),表示下面要求的数字的个数。
接下来有T行,每行有一个数字n(0<=n<=10^8),表示要求的二进制串。
输出:
输出共T行。每行输出求得的二进制串。
样例输入
5
23
535
2624
56275
989835
样例输出:
10111
1000010111
101001000000
1101101111010011
11110001101010001011
  思路:注意下n等于0的情况就可以了。

#include<stdio.h>

int main() {
    int T,a[31];
    scanf("%d",&T);
    while(T--) {
        int n;
        scanf("%d",&n);
        if(!n) {
            printf("0\n");
            continue;
        }
        int i = 0;
        while(n) {
            a[i++] = n % 2;
            n /= 2;
        } 
        for(int j = i - 1;j >= 0;j--) {
            printf("%d",a[j]);
        }
        printf("\n");
    }
}

Problem C. 矩阵幂
题目描述:
给定一个n*n的矩阵,求该矩阵的k次幂,即P^K。
输入:
输入包含多组测试数据。
数据的第一行为一个整数(0 < T <=10),表示要求矩阵的个数。
接下来有T组测试数据,每组测试数据格式如下:
第一行:两个整数n(2 <=n<=10)、k(1<=k<=5),两个数字之间用一个空格隔开,含义如上所示。
接下来有n行,每行n个正整数,其中,第i行第j个整数表示矩阵中第i行第j列的矩阵元素Pij(0 <= Pij <=10)。另外,数据保证最后结果不会超过10^8。
输出:
对于每组测试数据,输出其结果。格式为:
n行n列个整数,每行数之间用空格隔开,注意,每行最后一个数后面不应该有多余的空格。
样例输入:
3
2 2
9 8
9 3
3 3
4 8 4
9 3 0
3 5 7
5 2
4 0 3 0 1
0 0 5 8 5
8 9 8 5 3
9 6 1 7 8
7 2 5 7 3
样例输出:
153 96
108 81
1216 1248 708
1089 927 504
1161 1151 739
47 29 41 22 16
147 103 73 116 94
162 108 153 168 126
163 67 112 158 122
152 93 93 111 97
  思路:用矩阵快速幂会快点,不过应付机试,最朴素的解法就足够了。

#include<stdio.h>
#include<string.h>

int main() {
    int a[10][10],b[10][10],c[10][10];
    int T;
    scanf("%d",&T);
    while(T--) {
        int n,k;
        scanf("%d%d",&n,&k);
        for(int i = 0;i < n;i++) {
            for(int j = 0;j < n;j++) {
                scanf("%d",&a[i][j]);
                b[i][j] = a[i][j];
            }
        }
        k--;
        while(k--) {
            for(int i = 0;i < n;i++) {
                for(int j = 0;j < n;j++) {
                    c[i][j] = 0;
                    for(int l = 0;l < n;l++) {
                        c[i][j] += a[i][l] * b[l][j];
                    }
                }
            }
            for(int i = 0;i < n;i++) {
                for(int j = 0;j < n;j++) {
                    b[i][j] = c[i][j];
                }
            }
        }
        for(int i = 0;i < n;i++) {          
            for(int j = 0;j < n;j++) {
                if(j) {
                    printf(" %d",b[i][j]);
                } else {
                    printf("%d",b[i][j]);
                }              
            }
            printf("\n");
        }
    }     
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值