2012北邮计算机考研复试上机题解

A:二叉排序树

时间限制:1 秒

内存限制:128 兆

特殊判题:否

提交:3803

解决:1526

题目描述:

二叉排序树,也称为二叉查找树。可以是一颗空树,也可以是一颗具有如下特性的非空二叉树:

1. 若左子树非空,则左子树上所有节点关键字值均不大于根节点的关键字值;

2. 若右子树非空,则右子树上所有节点关键字值均不小于根节点的关键字值;

3. 左、右子树本身也是一颗二叉排序树。

  现在给你N个关键字值各不相同的节点,要求你按顺序插入一个初始为空树的二叉排序树中,每次插入后成功后,求相应的父亲节点的关键字值,如果没有父亲节点,则输出-1。

输入:

输入包含多组测试数据,每组测试数据两行。

第一行,一个数字N(N<=100),表示待插入的节点数。

第二行,N个互不相同的正整数,表示要顺序插入节点的关键字值,这些值不超过10^8。

输出:

输出共N行,每次插入节点后,该节点对应的父亲节点的关键字值。

样例输入:
5
2 5 1 3 4
样例输出:
-1
2
2
5
3
来源:
2012年北京邮电大学计算机研究生机试真题
题目地址:二叉排序树
解题思路:直接构建二叉排序树,每次从根节点出发。
如果比当前节点小,那么往当前节点左边找。
(1)如果当前节点有左孩子,那么递归到左孩子。
(2)如果当前节点没有左孩子,那么直接新建一个节点插入到左孩子上。
同理,如果比当前节点大,那么往当前节点右边找。
(1)如果当前节点有右孩子,那么递归到右孩子。
(2)如果当前节点没有右孩子,那么直接新建一个节点插入到右孩子上。
AC代码:
#include<iostream>
#include<cstdio>
using namespace std;

struct node
{
    node *lchild;
    node *rchild;
    int val;
}*root;

void dfs(node *p,int tmp)
{
    if(tmp<p->val)
    {
        if(p->lchild)
            dfs(p->lchild,tmp);
        else
        {
            node *t = new node;
            t->lchild=NULL;
            t->rchild=NULL;
            t->val=tmp;
            p->lchild=t;
            printf("%d\n",p->val);
            //printf("lchild %d\n",p->lchild->val);
            return;
        }
    }
    if(tmp>p->val)
    {
        if(p->rchild)
            dfs(p->rchild,tmp);
        else
        {
            node *t = new node;
            t->lchild=NULL;
            t->rchild=NULL;
            t->val=tmp;
            p->rchild=t;
            printf("%d\n",p->val);
            //printf("rchild %d\n",p->rchild->val);
            return;
        }
    }
}

int main()
{
    int n,tmp,i;
    while(~scanf("%d",&n))
    {
        scanf("%d",&tmp);
        node *t = new node;
        t->lchild=NULL;
        t->rchild=NULL;
        t->val=tmp;
        root=t;

        printf("-1\n");
        for(i=1; i<n; i++)
        {
            scanf("%d",&tmp);
            dfs(root,tmp);
        }
    }
    return 0;
}

/**************************************************************
    Problem: 1467
    User: 奔跑的菜鸟
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1520 kb
****************************************************************/

B:二进制数

时间限制:1 秒

内存限制:128 兆

特殊判题:否

提交:8654

解决:2395

题目描述:

  大家都知道,数据在计算机里中存储是以二进制的形式存储的。

  有一天,小明学了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
来源:
2012年北京邮电大学计算机研究生机试真题

题目地址:二进制数

解题思路:直接按位取保存到数组最后输出即可。
PS:0要特判!
AC代码:
#include<iostream>
#include<cstdio>
using namespace std;

int a[10005];

int main()
{
    int n,i,p,len;
    while(~scanf("%d",&n))
    {
        while(n--)
        {
            len=0;
            scanf("%d",&p);
            if(p==0)
            {
                printf("0\n");
                continue;
            }
            while(p)
            {
                a[len++]=p&1;
                p>>=1;
            }

            for(i=len-1;i>=0;i--)
                printf("%d",a[i]);
            printf("\n");
        }
    }
    return 0;
}

/**************************************************************
    Problem: 1473
    User: 奔跑的菜鸟
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1556 kb
****************************************************************/

C:矩阵幂

时间限制:1 秒

内存限制:128 兆

特殊判题:否

提交:4147

解决:1633

题目描述:

给定一个n*n的矩阵,求该矩阵的k次幂,即P^k。

输入:

输入包含多组测试数据。

数据的第一行为一个整数T(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
来源:
2012年北京邮电大学计算机研究生机试真题
题目地址:矩阵幂
解题思路:直接用矩阵乘就可以了。由于K的范围最大只到10。可以直接模拟矩阵乘。
如果想进阶看矩阵的快速幂:HDU3306Another kind of Fibonacci(简单矩阵快速幂)
AC代码:

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

int n;
int a[15][15];
int b[15][15];
int tmp[15][15];

void fun()
{
    int i,j,k;
    memset(tmp,0,sizeof(tmp));
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            for(k=0;k<n;k++)
            {
                tmp[i][j]+=b[i][k]*a[k][j];
            }
        }
    }

    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
            b[i][j]=tmp[i][j];
}

int main()
{
    int tes,i,j,k;
    cin>>tes;

    while(tes--)
    {
        cin>>n>>k;
        for(i=0;i<n;i++)
            for(j=0;j<n;j++)
            {
                cin>>a[i][j];
                b[i][j]=a[i][j];
            }

        k--;
        while(k--)
            fun();

        for(i=0;i<n;i++)
        {
            cout<<b[i][0];
            for(j=1;j<n;j++)
            {
                cout<<" "<<b[i][j];
            }
            cout<<endl;
        }
    }
    return 0;
}

/**************************************************************
    Problem: 1474
    User: 奔跑的菜鸟
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1520 kb
****************************************************************/

D:IP数据包解析

时间限制:1 秒

内存限制:128 兆

特殊判题:否

提交:4439

解决:612

题目描述:

我们都学习过计算机网络,知道网络层IP协议数据包的头部格式如下:

  

  其中IHL表示IP头的长度,单位是4字节;总长表示整个数据包的长度,单位是1字节。

  传输层的TCP协议数据段的头部格式如下:

  

  头部长度单位为4字节。

  你的任务是,简要分析输入数据中的若干个TCP数据段的头部。 详细要求请见输入输出部分的说明。

输入:

第一行为一个整数T,代表测试数据的组数。

以下有T行,每行都是一个TCP数据包的头部分,字节用16进制表示,以空格隔开。数据保证字节之间仅有一个空格,且行首行尾没有多余的空白字符。

保证输入数据都是合法的。

输出:

对于每个TCP数据包,输出如下信息:

Case #x,x是当前测试数据的序号,从1开始。

Total length = L bytes,L是整个IP数据包的长度,单位是1字节。

Source = xxx.xxx.xxx.xxx,用点分十进制输出源IP地址。输入数据中不存在IPV6数据分组。

Destination = xxx.xxx.xxx.xxx,用点分十进制输出源IP地址。输入数据中不存在IPV6数据分组。

Source Port = sp,sp是源端口号。

Destination Port = dp,dp是目标端口号。

对于每个TCP数据包,最后输出一个多余的空白行。

具体格式参见样例。

请注意,输出的信息中,所有的空格、大小写、点符号、换行均要与样例格式保持一致,并且不要在任何数字前输出多余的前导0,也不要输出任何不必要的空白字符。

样例输入:
2
45 00 00 34 7a 67 40 00 40 06 63 5a 0a cd 0a f4 7d 38 ca 09 cd f6 00 50 b4 d7 ae 1c 9b cf f2 40 80 10 ff 3d fd d0 00 00 01 01 08 0a 32 53 7d fb 5e 49 4e c8
45 00 00 c6 56 5a 40 00 34 06 e0 45 cb d0 2e 01 0a cd 0a f4 00 50 ce 61 e1 e9 b9 ee 47 c7 37 34 80 18 00 b5 81 8f 00 00 01 01 08 0a 88 24 fa c6 32 63 cd 8d
样例输出:
Case #1
Total length = 52 bytes
Source = 10.205.10.244
Destination = 125.56.202.9
Source Port = 52726
Destination Port = 80

Case #2
Total length = 198 bytes
Source = 203.208.46.1
Destination = 10.205.10.244
Source Port = 80
Destination Port = 52833
来源:
2012年北京邮电大学计算机研究生机试真题
题目地址:IP数据包解析
解题思路:需要得到下列信息:
1.IP数据包总长度,根据第3-4字节得到
2.源地址:13-16字节。目的地址:17-20字节
3.源端口号:len1+1到len1+2字节。目的端口号:len1+3到len1+4字节
(len1表示ip头部长度:第一个字节低四位可以得到)
(len2表示tcp头部长度:在第len1+13字节的高四位可以得到)
不过很不幸代码WA掉了,觉得处理的是没有问题的。测试样例是OK的。
而且思路也很清晰。
附上代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

int tl;
int s[4];
int d[4];

int sp;
int dp;

char str[2];

int toint(char x)
{
    if(x>='0'&&x<='9')
        return x-'0';
    else
        return x-'a'+10;
}

int main()
{
    int tes,i,j;
    cin>>tes;

    for(int cas=1;cas<=tes;cas++)
    {
        tl=0;
        s[0]=s[1]=s[2]=s[3]=0;
        d[0]=d[1]=d[2]=d[3]=0;
        sp=dp=0;

        cin>>str;
        int len1=toint(str[1])*4;
        cin>>str;

        for(i=3;i<=4;i++)
        {
            cin>>str;
            for(j=0;j<2;j++)
                tl=tl*16+toint(str[j]);
        }
        for(i=5;i<=12;i++)
            cin>>str;
        for(i=13;i<=16;i++)
        {
            cin>>str;
            for(j=0;j<2;j++)
            {
                s[i-13]=s[i-13]*16+toint(str[j]);
            }
        }
        for(i=17;i<=20;i++)
        {
            cin>>str;
            for(j=0;j<2;j++)
            {
                d[i-17]=d[i-17]*16+toint(str[j]);
            }
        }
        for(i=21;i<=len1;i++)
            cin>>str;
        for(i=len1+1;i<=len1+2;i++)
        {
            cin>>str;
            for(j=0;j<2;j++)
                sp=sp*16+toint(str[j]);
        }
        for(i=len1+3;i<=len1+4;i++)
        {
            cin>>str;
            for(j=0;j<2;j++)
                dp=dp*16+toint(str[j]);
        }
        for(i=len1+5;i<=len1+12;i++)
            cin>>str;
        cin>>str;
        int len2 = toint(str[0])*4;

        for(i=len1+14;i<=len1+len2;i++)
            cin>>str;
        printf("Case #%d\n",cas);
        printf("Total length = %d bytes\n",tl);
        printf("Source = %d.%d.%d.%d\n",s[0],s[1],s[2],s[3]);
        printf("Destination = %d.%d.%d.%d\n",d[0],d[1],d[2],d[3]);
        printf("Source Port = %d\n",sp);
        printf("Destination Port = %d\n\n",dp);
    }
    return 0;
}

然后找了一个AC的代码。
他的处理思路是直接将最开始的用字符串gets一行得到,然后去除空格,然后得到信息。
这样就不需要管TCP头有多长了。
AC代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>  

#define LEN 1000  

int change_tint(char *str, int begin, int num)
{
    int i;
    char *temp = (char *)malloc(sizeof(char) * (num + 1));  

    for(i = 0; i < num; i ++) {
        temp[i] = str[begin + i];
    }
    temp[i] = '\0';  

    return strtol(temp, NULL, 16);
}  

void ip_field(char *str, int begin, int num)
{
    int i, flag, ip;
    for (i = 0, flag = 1; i < num; i += 2) {
        ip = change_tint(str, begin + i, 2);
        printf("%d", ip);
        if (flag <= 3) {
            printf(".");
            flag ++;
        }
    }
    printf("\n");
}  

int main()
{
    int index, i, j, n, length, ihl;
    char ipstr[LEN], temp[LEN];  

    while (scanf("%d\n", &n) != EOF) {
        if (n != 0) {
            for (index = 1; index <= n; index ++) {
                memset(ipstr, 0, sizeof(ipstr));
                memset(temp, 0, sizeof(temp));
                gets(temp);
                // 去除空格
                for (i = j = 0, length = strlen(temp); i < length; i ++) {
                    if (temp[i] != ' ') {
                        ipstr[j ++] = temp[i];
                    }
                }
                ipstr[j] = '\0';  

                // 当前测试数据的序号
                printf("Case #%d\n", index);  

                // 整个ip数据包的长度
                length = change_tint(ipstr, 4, 4);
                printf("Total length = %d bytes\n", length);  

                // 源ip地址和目的ip地址
                printf("Source = ");
                ip_field(ipstr, 24, 8);
                printf("Destination = ");
                ip_field(ipstr, 32, 8);  

                // 源端口号和目的端口号
                ihl = change_tint(ipstr, 1, 1) * 4 * 2;
                printf("Source Port = %d\n", change_tint(ipstr, ihl, 4));
                printf("Destination Port = %d\n", change_tint(ipstr, ihl + 4, 4));
                printf("\n");
            }
        }
    }
    return 0;
}  

望走过的小伙伴们感兴趣的帮博主找找bug,感激不尽~

时间: 2024-10-16 08:09:43

2012北邮计算机考研复试上机题解的相关文章

HDU 1234 (浙大计算机研究生复试上机考试-2005年) 开门人和关门人 (水)

开门人和关门人 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 11133    Accepted Submission(s): 5667 Problem Description 每天第一个到机房的人要把门打开,最后一个离开的人要把门关好.现有一堆杂乱的机房签 到.签离记录,请根据记录找出当天开门和关门的人. Input 测试输入的第一

hdu 4416 水题 浙大计算机研究生复试上机考试-2005年 可是发现自己写代码有问题

Spring3与Hibernate4整合时出现了nested exception is java.lang.NoClassDefFoundError: Lorg/hibernate/cache/CacheProvider. hibernate3的时候,用spring来控制sessionfactory用的可以是org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean,因为用的是hibernate4所以照猫画

北京航空航天大学计算机系考研复试上机真题及答案---2014

第一题,阶乘数. 输入一个正整数,输出时,先输出这个数本身,跟着一个逗号,再输出这个数的各位数字的阶乘和,等号,阶乘和的计算结果,并判断阶乘和是否等于原数,如果相等输出Yes,否则输出No.题目说明输入的正整数以及其各位阶乘和都不会超出int型的表示范围. 输入样例1: 145 输出样例1: 145,1!+4!+5!=145 Yes 输入样例2: 1400 输出样例2: 1400,1!+4!+0!+0!=27 No 第二题,五子棋. 输入一个19*19的矩阵,只包含数字0.1.2,表示两人下五子

浙大计算机研究生复试上机考试-2010年 zoj问题

ZOJ问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2984 Accepted Submission(s): 906 Problem Description 对给定的字符串(只包含'z','o','j'三种字符),判断他是否能AC. 是否AC的规则如下: 1. zoj能AC: 2. 若字符串形式为xzojx,则也能AC,其中x可以是N

浙大计算机研究生复试上机考试-2010年 最短路径问题

最短路径问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 14405 Accepted Submission(s): 4408 Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的. Input 输入n,m

计算机考研复试真题 众数

题目描述 输入20个数,每个数都在1-10之间,求1-10中的众数(众数就是出现次数最多的数,如果存在一样多次数的众数,则输出权值较小的那一个). 输入描述: 测试数据有多组,每组输入20个1-10之间的数. 输出描述: 对于每组输入,请输出1-10中的众数. 示例1 输入 5 1 5 10 3 5 3 4 8 6 8 3 6 5 10 7 10 2 6 2 输出 5 //计算机考研复试真题 众数 /* 程序设计思想:假双数组法,数组值存放出现的次数,数组下标存放对应的数. */ //程序实现:

计算机考研复试 A+B

题目描述 读入两个小于100的正整数A和B,计算A+B. 需要注意的是:A和B的每一位数字由对应的英文单词给出. 输入描述: 测试输入包含若干测试用例,每个测试用例占一行,格式为"A + B =",相邻两字符串有一个空格间隔.当A和B同时为0时输入结束,相应的结果不要输出. 输出描述: 对每个测试用例输出1行,即A+B的值. 示例1 输入 one + two = three four + five six = zero seven + eight nine = zero + zero

计算机考研复试面试常问问题 计算机网络篇(下)

计算机考研复试面试常问问题 计算机网络篇(下) 在复习过程中,我用心查阅并整理了在考研复试面试中可能问到的大部分问题,并分点整理了答案,可以直接理解背诵并加上自己的语言润色!极力推荐打印下来看,效率更高!绝对良心之作! 此系列一共有8篇:编程语言篇|数据结构篇|操作系统篇|组成原理篇|计算机网络篇|数据库篇|软件工程篇|计算机专业英语篇(还未全部完成,敬请期待,你们的支持和关注是我最大的动力!) 个人整理,不可用于商业用途,转载请注明出处. 作者各个平台请搜索:程序员宝藏.快来探索属于你的宝藏吧

计算机考研复试面试系列 计算机专业英语篇

计算机考研复试面试系列 计算机专业英语篇 在复习过程中,我用心查阅并整理了在考研复试面试中可能问到的大部分问题,并分点整理了答案,可以直接理解背诵并加上自己的语言润色!极力推荐打印下来看,效率更高! 此系列一共有8篇:编程语言篇|数据结构篇|操作系统篇|组成原理篇|计算机网络篇|数据库篇|软件工程篇|计算机专业英语篇(还未全部完成,敬请期待,你们的支持和关注是我最大的动力!) 个人整理,不可用于商业用途,转载请注明出处. 作者各个平台请搜索:程序员宝藏.快来探索属于你的宝藏吧! 需要pdf直接打