数据结构机试练习

问题 A: 谁是你的潜在朋友

时间限制: 1 Sec 内存限制: 32 MB

题目描述
“臭味相投”——这是我们描述朋友时喜欢用的词汇。两个人是朋友通常意味着他们存在着许多共同的兴趣。然而作为一个宅男,你发现自己与他人相互了解的机会 并不太多。幸运的是,你意外得到了一份北大图书馆的图书借阅记录,于是你挑灯熬夜地编程,想从中发现潜在的朋友。
首先你对借阅记录进行了一番整理,把N个读者依次编号为1,2,…,N,把M本书依次编号为1,2,…,M。同时,按照“臭味相投”的原则,和你喜欢读同一本书的人,就是你的潜在朋友。你现在的任务是从这份借阅记录中计算出每个人有几个潜在朋友。

输入
每个案例第一行两个整数N,M,2 <= N ,M<= 200。接下来有N行,第i(i = 1,2,…,N)行每一行有一个数,表示读者i-1最喜欢的图书的编号P(1<=P<=M)

输出
每个案例包括N行,每行一个数,第i行的数表示读者i有几个潜在朋友。如果i和任何人都没有共同喜欢的书,则输出“BeiJu”(即悲剧,^ ^)

样例输入
4 5
2
3
2
1
样例输出
1
BeiJu
1
BeiJu

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<time.h>
int main(){
	int m[202] = {0};	
	int n[202] = {0};
	int a,b,i;
	while(scanf("%d %d",&a,&b)!=EOF){
	for (i=1; i<=b; i++)  
            m[i] = 0;  
	for(i = 1;i <= a;i++){
		scanf("%d",&n[i]);
		m[n[i]]++;
	} 
	for(i = 1;i<=a;i++){
		if(m[n[i]]==1)
			printf("BeiJu\n");

		else
			printf("%d\n",m[n[i]]-1);
	}
	}
	
return 0;}

这个有两个问题,全部初始化可以用{0},另一个是题目未明确说明只有一个案例的时候,使用while循环处理

问题 B: Course List for Student (25)

时间限制: 1 Sec 内存限制: 32 MB
题目描述
Zhejiang University has 40000 students and provides 2500 courses. Now given the student name lists of all the courses, you are supposed to output the registered course list for each student who comes for a query.
输入
Each input file contains one test case. For each case, the first line contains 2 positive integers: N (<=40000), the number of students who look for their course lists, and K (<=2500), the total number of courses. Then the student name lists are given for the courses (numbered from 1 to K) in the following format: for each course i, first the course index i and the number of registered students Ni (<= 200) are given in a line. Then in the next line, Ni student names are given. A student name consists of 3 capital English letters plus a one-digit number. Finally the last line contains the N names of students who come for a query. All the names and numbers in a line are separated by a space.
输出
For each test case, print your results in N lines. Each line corresponds to one student, in the following format: first print the student’s name, then the total number of registered courses of that student, and finally the indices of the courses in increasing order. The query results must be printed in the same order as input. All the data in a line must be separated by a space, with no extra space at the end of the line.
样例输入
11 5
4 7
BOB5 DON2 FRA8 JAY9 KAT3 LOR6 ZOE1
1 4
ANN0 BOB5 JAY9 LOR6
2 7
ANN0 BOB5 FRA8 JAY9 JOE4 KAT3 LOR6
3 1
BOB5
5 9
AMY7 ANN0 BOB5 DON2 FRA8 JAY9 KAT3 LOR6 ZOE1
ZOE1 ANN0 BOB5 JOE4 JAY9 FRA8 DON2 AMY7 KAT3 LOR6 NON9
样例输出
ZOE1 2 4 5
ANN0 3 1 2 5
BOB5 5 1 2 3 4 5
JOE4 1 2
JAY9 4 1 2 4 5
FRA8 3 2 4 5
DON2 2 4 5
AMY7 1 5
KAT3 3 2 4 5
LOR6 4 1 2 4 5
NON9 0

二叉查找树和层序遍历

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<time.h>
#include<vector>
#include<queue>
using namespace std;
struct tree{
	int data;
	tree* lchild;
	tree* rchild;
};
bool bol = true;
tree* root = NULL;
tree* newNode(int v){
	tree* t = new tree;
	t->data = v;
	t->rchild = t->lchild=NULL;
	return t;
}
void insert(tree* &t,int v){
	if(t == NULL){
		t = newNode(v);
		return;
	}
	if(v>t->data){
		insert(t->rchild,v);
	}else{
		insert(t->lchild,v);
	}
}
	void search(tree* t,reee* t1){
		queue<tree*> q;
		
		q.push(t);
		
		while(!q.empty()){
			tree* r = q.front();
			printf("%d",r->data);
			q.pop();
			if(r->lchild!=NULL){
				q.push(r->lchild);}
			if(r->rchild!=NULL){
				q.push(r->rchild);}
			if(q.size()>0){
				printf(" ");}
		
		}
	
}

int main(){
	int i,j,k;
	scanf("%d",&i);
	for(j = 0;j < i;j++){
		scanf("%d",&k);
		insert(root,k);
	}
	search(root);
return 0;}

二叉查找树的比较与后序遍历

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<time.h>
#include<vector>
#include<queue>
using namespace std;
struct tree{
	int data;
	tree* lchild;
	tree* rchild;
};
bool bol = true;
int num = 1;
tree* root = NULL;
tree* root1 = NULL;
tree* newNode(int v){
	tree* t = new tree;
	t->data = v;
	t->rchild = t->lchild=NULL;
	return t;
}
void insert(tree* &t,int v){
	if(t == NULL){
		t = newNode(v);
		return;
	}
	if(v>t->data){
		insert(t->rchild,v);
	}else{
		insert(t->lchild,v);
	}
}
void search(tree* t){
		queue<tree*> q;
		q.push(t);
		while(!q.empty()){
			tree* r = q.front();
			printf("%d",r->data);
			q.pop();
			if(r->lchild!=NULL){
				q.push(r->lchild);}
			if(r->rchild!=NULL){
				q.push(r->rchild);
			}
			if(q.size()>0){
				printf(" ");}
			else{
			}
		
		}
	
}
void search2(tree* t,int i){
	if(t == NULL){
		return;}
	search2(t->lchild,i);
	search2(t->rchild,i);
	printf("%d",t->data);
	while(num<i){
	printf(" ");
	num++;
	break;
	}
}
void compare(tree* t,tree* t1){
		queue<tree*> q;
		queue<tree*> q2;
		q.push(t);
		q2.push(t1);
		while(!q.empty()){
			if(q2.empty()){
				bol = false;
			}
			tree* r = q.front();
			tree* r2;
			if(bol){
				r2 = q2.front();
				if(bol&&(r2->data != r->data)){
					bol = false;
				}
			}
			q.pop();
			if(bol){
				q2.pop();}
			if(r->lchild!=NULL){
				if(bol&&r2->lchild!=NULL){
					q2.push(r2->lchild);
				}else{
					bol = false;
				}
				q.push(r->lchild);}
			if(r->rchild!=NULL){
				q.push(r->rchild);
				if(bol&&r2->rchild!=NULL){
					q2.push(r2->rchild);
				}else{
					bol = false;
				}
			}
		
		}
	
}

int main(){
	int i,j,k;
	scanf("%d",&i);
	for(j = 0;j < i;j++){
		scanf("%d",&k);
		insert(root,k);
		
	}
	for(j = 0;j < i;j++){
		scanf("%d",&k);
		insert(root1,k);
		
	}
	compare(root,root1);
	if(bol){
		printf("YES\n");}
	else{
		printf("NO\n");
	}
	search2(root,i);
	printf("\n");
	search(root);

return 0;}

search1是后序遍历,search是层序遍历

1024宇宙树

Problem Description

在传承至今的典籍中认为,每个宇宙都是十种宇宙中的一种:炎之宇宙、光之宇宙、冰之宇宙、风之宇宙、雷之宇宙、土之宇宙、水之宇宙、木之宇宙、钢之宇宙、暗之宇宙,各表示了一个宇宙内部的主要元素。在最初始的大爆炸之后,在混沌中产生了最初的若干个宇宙,这些宇宙的类型是以上十种之一,可能相同,可能不同。从这些宇宙开始,每过一个纪元,各个宇宙都有可能孕育出多个新的宇宙(类型可能相同,可能不同)。可以预见,从任何一个初始宇宙开始,在经过若干个纪元之后,就有可能得到非常多新的宇宙。

在更高的维度上,一种名为“孵化者”的生物在观测着这些宇宙。“孵化者”们把宇宙之间的孕育关系表示成一棵树,称为“宇宙树”。下图便是一棵可能的宇宙树,其中用0~9来分别代表十种宇宙的类型,那么这棵宇宙树便是从一个类型为2的初始宇宙开始,孕育出了类型分别为6、1、2的三个宇宙,而类型为6的那个宇宙又孕育出了类型为0和9的两个宇宙,类型为2的那个非初始宇宙孕育出了类型为5的宇宙。

“孵化者”们发现,一个宇宙与它孕育出的新宇宙之间并不是完全没有联系的,旧宇宙的信息会被携带一部分到新的宇宙中。它们猜想,既然宇宙类型的生成是“随机”的,那么在很多很多个纪元之后,再孕育出的新宇宙,其宇宙内部很可能会是十种元素达到平衡的状态。“孵化者”们认为,可以观测就可以干涉,可以干涉就可以控制,那么研究当前这些宇宙的类型便十分重要。

“孵化者”们认为,每一个处于宇宙树叶结点的宇宙,都是其所在分支上的最新宇宙,可以把这些叶结点的宇宙称为“新宇宙”。根据它们的猜想,这些宇宙的类型虽然从主要元素上来说属于十种中的一种,但如果把它们划分得更细致的话,是可以得到更准确的类型信息的。“孵化者”们把一个宇宙的“准确类型”定义为:从单棵宇宙树的初始宇宙开始、沿着孕育关系向下到达该宇宙的过程中形成的路径上的各类型的拼接结果就是这个宇宙的“准确类型”。例如在上图中,主类型为0的宇宙的“准确类型”是260,主类型为9的的宇宙的“准确类型”是269,主类型为1的的宇宙的“准确类型”是21,主类型为5的宇宙的“准确类型”是225。

为了研究宇宙类型的混合结果,“孵化者”们把一棵宇宙树的所有“新宇宙”的“准确类型”求和,并将得到的结果称为这棵宇宙树的类型,这有助于它们进行下一步研究。例如对上面的图来说,这棵宇宙树的类型便是260+269+21+225=775。

现在“孵化者”们想知道,当前存在的所有宇宙树的类型分别是什么。
Input

每个输入文件中一组数据。
对每组数据,第一行为两个正整数N(1 <= N <= 10000, 0 <= M < N),分别表示宇宙的个数与孕育关系的条数。假设宇宙的编号为0~N-1,且每棵宇宙树的初始宇宙的编号一定是这棵宇宙树中最小的。
接下来一行N个整数,其中第i个整数表示编号为i-1的宇宙的主类型。
接下来M行,每行两个整数u和v(0 <= u < N, 0 <= v < N, u != v),表示编号为u的宇宙孕育了编号为v的宇宙。数据保证同一对(u,v)只会出现一次。
Output

第一行一个整数,表示宇宙树的个数K。
第二行K个整数,分别表示这K个宇宙树的类型。输出顺序为,如果一棵宇宙树的初始宇宙编号比其他宇宙树的小,那么就优先输出。
行末不允许有多余的空格。
Sample Input

10 8
2 6 1 2 0 9 5 0 3 6
0 1
0 2
0 3
1 4
1 5
3 6
7 8
8 9
Sample Output

2
775 36
Author

Shoutmon
Source

18浙大考研机试模拟赛

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<time.h>
#include<vector>
#include<queue>
using namespace std;
int seTree = 0;
vector<int > se[10001];
vector<int> metri[10001]; 
vector<int> v;
int jilu[10001] = {0};
void bianli(int in,int num){
	if(metri[in].size()<1){
		se[seTree-1].push_back(num);
		return;
	}
	int n1;
	for(n1 =0; n1 < metri[in].size();n1++){
		if(jilu[metri[in][n1]]==0){
			if(jilu[in]==0){
				seTree++;
			}
		}
		jilu[in]++;
		jilu[metri[in][n1]]++;
		int tem = num*10 + v[metri[in][n1]];
		bianli(metri[in][n1],tem);
	}
}
int main(){
	int i ,j,k,m,n;

	scanf("%d%d",&j,&k);
	for(i = 0;i < j;i++){
		scanf("%d",&m);
		v.push_back(m);
	}
	for(i = 0;i < k;i++){
		scanf("%d %d",&m,&n);
		metri[m].push_back(n);
	}
	for(i = 0;i < j;i++){
		if(jilu[i] == 0){
			bianli(i,v[i]);
		}
	}
	int temp;
	printf("%d\n",seTree);
	for(i = 0;i < seTree;i++){
		temp = 0;
		for(m = 0;m < se[i].size();m++){
			temp += se[i][m];
		}
		printf("%d",temp);
		if(i != seTree-1){
			printf(" ");
		}
	}
return 0;}


只跑成功了测试案例

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值