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 <bits/stdc++.h>
using namespace std;
struct node{
	int data;
	node* l;
	node* r;
	node(int data):data(data),l(NULL),r(NULL) {}
}; 
node* insert(node* t,int x,int fa){
	if(t==NULL){
		t=new node(x);
		printf("%d\n",fa);
	}
	else if(t->data>x)
		t->l=insert(t->l,x,t->data);
	else if(t->data<x)
		t->r=insert(t->r,x,t->data); 
	return t;
}
int main(){
	int n;
    while(scanf("%d",&n)!=EOF){
    	node* t=NULL;
    	for(int i=0;i<n;i++){
			int x;
			scanf("%d",&x);
			t=insert(t,x,-1);
    	}
    }
    return 0;
}

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

#include <bits/stdc++.h>
using namespace std;
int main(){
	int n;
    while(scanf("%d",&n)!=EOF){
    	vector<int> bin;
    	for(int i=0;i<n;i++){
    		bin.clear();
			int x;
			scanf("%d",&x);
			while(x!=0){
			bin.push_back(x%2);
			x/=2;
		}
			for(int i=bin.size()-1;i>=0;i--)
				printf("%d",bin[i]);
			printf("\n");
    	}
    }
    return 0;
}

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 <bits/stdc++.h>
using namespace std;
struct matrix{
	int m[10][10];
	int r,c;
	matrix(int r,int c):r(r),c(c) {}
	void input(){
		for(int i=0;i<r;i++)
			for(int j=0;j<c;j++)
				scanf("%d",&m[i][j]);
	}
	void output(){
		for(int i=0;i<r;i++){
			for(int j=0;j<c;j++){
				if(j!=0) printf(" ");
				printf("%d",m[i][j]);
			}
			printf("\n");
		}
	}
	matrix mmul(matrix y){
		matrix z(r,y.c);
		for(int i=0;i<r;i++)
			for(int j=0;j<y.c;j++){
				z.m[i][j]=0;
				for(int k=0;k<c;k++)
					z.m[i][j]+=m[i][k]*y.m[k][j];
			}
		return z;
	}
};
matrix mfaste(matrix x,int k){
	matrix ans(x.r,x.c);
	for(int i=0;i<x.r;i++)
		for(int j=0;j<x.c;j++){
			if(i==j) ans.m[i][j]=1;
			else ans.m[i][j]=0;
		}
	while(k!=0){
		if(k%2==1)
			ans=ans.mmul(x);
		k/=2;
		x=x.mmul(x);
	}
	return ans; 
}
int main(){
	int n;
    while(scanf("%d",&n)!=EOF){
    	for(int i=0;i<n;i++){
			int x,k;
			scanf("%d%d",&x,&k);
			matrix m(x,x);
			m.input();
			m.output();
			mfaste(m,k).output();
		}
    }
    return 0;
}

Problem D. IP数据包解析
题目描述:
我们都学过计算机网络,知道网络层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
两个8位的进位是16^2,若出现换行导致无法输出的问题要想到用getchar()

#include <bits/stdc++.h>
using namespace std;
int ctoi(char c){
	if(c>='0'&&c<='9')
		return c-'0';
	else if(c>='a'&&c<='z')
		return c-'a'+10;
}
void split(string str,vector<int> &twob){
	for(int i=0,j=0;i<str.size();i++){
		if(str[i]==' '){
			j++;
			twob.push_back(0);
		}else
			twob[j]=twob[j]*16+ctoi(str[i]);
	}
}
int main(){
	int n;
    while(scanf("%d",&n)!=EOF){
    	for(int i=1;i<=n;i++){
    		getchar();
    		string str;
    		getline(cin,str);
    		vector<int> twob;
			twob.push_back(0);
			split(str,twob);
			int len;
			len=twob[2]*16*16+twob[3];
			int sor[4],des[4];
			for(int j=0;j<4;j++){
				sor[j]=twob[12+j];
				des[j]=twob[16+j];
			}
			int sp,dp;
			sp=twob[20]*16*16+twob[21];
			printf("%d\n",twob[21]);
			dp=twob[22]*16*16+twob[23];
			printf("Case#%d\nTotal length=%d bytes\nScource=%d.%d.%d.%d\nDestination=%d.%d.%d.%d\nSource Port=%d\nDestination Port=%d\n"
			,i,len,sor[0],sor[1],sor[2],sor[3],des[0],des[1],des[2],des[3],sp,dp);
		}
    }
    return 0;
}

网研

打印字符串
给一串字符串,统计其中某个字符的个数。
Input
首先输入-一个整数T,表示一共有T组数据0<T<=10。
接下来每行一个字母x(x为az或者‘A’ -Z’)。
然后下面一-行输入一个字符串s(0<s的长度<1000)。
Output
统计这个字母在这个字符串中出现的次数。
Sample Input
2
a
absd
b
bbssb
Sample Output
1
3

#include <bits/stdc++.h>
using namespace std;
int main(){
	int n;
    while(scanf("%d",&n)!=EOF){
    	for(int i=1;i<=n;i++){
    		getchar();
    		char c;
    		int cnt=0;
    		scanf("%c",&c);
    		string str;
    		cin>>str;
    		for(int i=0;i<str.size();i++)
    			if(str[i]==c) cnt++;
    		printf("%d\n",cnt);
		}
    }
    return 0;
}

二叉树的层数
给一个二叉树
请把这个棵二叉树按层来打印。如果为相同层,需要从左到右打印。一个节点是先添加左节点后添加右节点,即添加顺序与输入顺序-致。
Input
首先输入一个整数T,表示一共有T组数据0<T<=10
再输入两个整数N,M(0<=N,M<=100)
表示下面有N行,这个树有M个节点(1号节点是这棵树的根节点)
每一行两个整数a,b(1<=a,b<=M)
表示节点a的父亲是节点b
Output
对于每组
先输出一行"Qi:"表示第i个问题
然后接下来输出每个问题二叉树每层的节点,在同一层的节点用空格分开,同一层输出在一行(每一行末尾没有空格),不同的层输出在不同行(如下面Sample Ouput所示)
Sample Input
2
4 5
2 1
3 1
4 2
5 4
1 2
2 1
Sample Output
Q1:
1
2 3
4
5
Q2:
1
2
处理高度,不需要定义二叉树

#include <bits/stdc++.h>
using namespace std;
int main(){
	int t;
	int h[101];
    while(scanf("%d",&t)!=EOF){
    	for(int i=1;i<=t;i++){
    		memset(h,0,sizeof(h));
    		int n,m;
    		scanf("%d%d",&n,&m);
    		h[1]=1;
    		for(int j=0;j<n;j++){
    			int a,b;
    			scanf("%d%d",&a,&b);
    			h[a]=h[b]+1;
    		}
    		printf("Q%d:\n",i);
    		int cur=1;
    		for(int j=1;j<=m;j++){
    			if(h[j]>cur){
    				printf("\n%d ",j);
    				cur++;
    			}
    			else printf("%d ",j);
    		}
    		printf("\n");
		}
    }
    return 0;
}

Ip地址
我们都学过计算机网络,了 解IPV4地址的点分十进制表示法。
你的任务很简单:判断-一个字符串是否是一个合法的点分十进制表示的IPV4地址。
最低的IP地址是0.0.0.0,最高的IP地址是255.255.255.255.
PS :方便起见,认为形似00.00.00.00的IP地址也是合法的。
Input
第一行是一个整数T,代表输入还剩下T行
以下的T行,每行都是一一个字符串(不含空白字符)。字符串的长度保证不超过15,不小于
1.
Output
对于每个字符串,输出一行。
如果它是-一个合法的IPV4地址,输出Yes。
否则,输出No。
Sample Input
3
59.64.130.18
f.a.t.e
1.23.45.678
Sample Output
Yes
No
No

#include <bits/stdc++.h>
using namespace std;
bool split(string str){
	int s[4];
	s[0]=0;
	for(int i=0,j=0;i<str.size();i++){
		if(str[i]=='.')
			s[++j]=0;
		else{
			if(str[i]<'0'||str[i]>'9') return false;
			s[j]=s[j]*10+str[i]-'0';
		}
	}
	for(int i=0;i<4;i++)
		if(s[i]<0||s[i]>255) return false;
	return true;
}
int main(){
	int t;
    while(scanf("%d",&t)!=EOF){
    	for(int i=1;i<=t;i++){
    		string str;
    		cin>>str;
    		puts(split(str)?"Yes":"No");
    	}
    }
    return 0;
}

最远距离
正义的伙伴諜祈和葬仪社的机器人Fuyuneru正在被邪恶的GHQ部队追杀。眼看着快要逃不掉了,祈就把重要的东西塞到了机器人体内,让它先跑,自己吸引火力。
假设Fuyuneru带上东西开始逃跑时所处的点为原点,朝向为正北。操纵FuyuNeru的指令有
如下四种:
rightX: X是1-359之间的整数,Fuyuneru 的前进方向顺时针转X度。
left X:X是1-359之间的整数,Fuyuneru的前进方向逆时针转X度。
forward X: X是整数(0<=X<=1000),Fuyuneru 向当前朝向前进X米。
backward X: X是整数(0<=X<=1000),Fuyuneru 向当前朝向后退X米。
现在祈向Fuyuneru 体内输入了N(1<=N<=50)个这样的指令。可是由于此前Fuyuneru被GHQ
部队击中,它出了一-点小问题:这N个指令执行的顺序是不确定的。
问: Fuyuneru 最远可能逃出多远?
即,Fuyuneru 在执行完N条指令之后,距离原 点最远的可能距离是多少?
Input
第一行是一个整数T,代表测试数据有T组。
每组测试数据中,第- -行是-一个整数N,代表指令有N条;
随后紧跟N行,每一行代表-一个指令(格式保证是上述四种中的-种,数据保证合法)。
Output
对于每组数据,输出一行:最远的可能逃亡距离,精确到小数点后3位。
Sample Input
3
3
forward 100
backward 100
left 90
4
left 45
forward 100
right 45
forward 100
6
left 10
forward 40
right 30
left 10
backward 4
forward 4
Sample Output
141.421
200.000
40.585

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值