北京邮电大学2010年计算机方向复试上机题 解题报告

九度OJ 题目1169:比较奇偶数个数
时间限制:1 秒  内存限制:32 兆  特殊判题:否  提交:1368  解决:329
题目描述:
    第一行输入一个数,为n,第二行输入n个数,这n个数中,如果偶数比奇数多,输出NO,否则输出YES。
输入:
    输入有多组数据。
    每组输入n,然后输入n个整数(1<=n<=1000)。
输出:
    如果偶数比奇数多,输出NO,否则输出YES。
样例输入:
    5
    1 5 2 4 3
样例输出:
    YES

前两道都是典型送分题 属于十分钟做完一两次提交就能AC的题目 但想不明白为啥解决率只在1/4左右、和最后一道个人觉得有一定难度的哈夫曼树解决率很接近 百思不得其解啊

//北邮2010计算机:题目1169:比较奇偶数个数 
//(1<=n<=1000)
#include <fstream>
#include <iostream>
using namespace std;

int main()
{
	int i, j, k, n, m;
	int even, odd;
	ifstream cin("BUPT_1169.txt");//
	while( cin >> n ){
		even = odd = 0;
		for( i=0; i<n; i++ ){
			cin >> m;
			if( m % 2 == 0 )
				even++;
			else odd++;
		}
		if( even > odd )
			cout << "NO\n";
		else cout << "YES\n";
	}
	system("pause");//
	return 0;
}

九度OJ 题目1170:找最小数
时间限制:1 秒  内存限制:32 兆   特殊判题:否   提交:752  解决:280
题目描述:
    第一行输入一个数n,1 <= n <= 1000,下面输入n行数据,每一行有两个数,分别是x y。输出一组x y,该组数据是所有数据中x最小,且在x相等的情况下y最小的。
输入:
    输入有多组数据。
    每组输入n,然后输入n个整数对。
输出:
    输出最小的整数对。
样例输入:
    5  
    3 3  
    2 2  
    5 5  
    2 1  
    3 6
样例输出:
    2 1

//北邮2010计算机:1170:找最小数
//(1<=n<=1000)
#include <fstream>
#include <algorithm>
#include <iostream>
using namespace std;
struct NUMBER{
	int x, y;
};
NUMBER a[1000];

bool cmp( NUMBER a, NUMBER b ){
	if( a.x == b.x )
		return a.y < b.y;
	else return a.x < b.x;

};

int main()
{
	int i, j, k, n, m;
	ifstream cin("BUPT_1170.txt");//
	while( cin >> n ){
		for( i=0; i<n; i++ )
			cin >> a[i].x >> a[i].y;
		sort(a,a+n,cmp);
		cout << a[0].x << " " << a[0].y << endl;
	}
	system("pause");//
	return 0;
}

九度OJ 题目1171:C翻转
时间限制:1 秒  内存限制:32 兆  特殊判题:否  提交:481  解决:131
题目描述:
    首先输入一个5 * 5的数组,然后输入一行,这一行有四个数,前两个代表操作类型,后两个数x y代表需操作数据为以x y为左上角的那几个数据。
    操作类型有四种:
    1 2 表示:90度,顺时针,翻转4个数
    1 3 表示:90度,顺时针,翻转9个数
    2 2 表示:90度,逆时针,翻转4个数
    2 3 表示:90度,逆时针,翻转9个数
输入:
    输入有多组数据。
    每组输入一个5 * 5的数组,然后输入一行,这一行有四个数,前两个代表操作类型,后两个数x y代表需操作数据为以x y为左上角的那几个数据。
输出:
    输出翻转后的数组。
样例输入:
    1 2 3 4 5
    6 7 8 9 10
    11 12 13 14 15
    16 17 18 19 20
    21 22 23 24 25
    1 3 1 1
样例输出:
    11 6 1 4 5
    12 7 2 9 10
    13 8 3 14 15
    16 17 18 19 20
    21 22 23 24 25

有点难度的一道题 一行一行[或列]的单独写出该行[或列]的旋转for循环之后 再从中发现规律组合成双层循环 会更容易解决 另外需要注意扩充数组到7行7列 因为可能给定坐标过于偏右下使得实际有效旋转数据不足4或9个 这时要用扩充的0来代替

//北邮2010计算机:1171:C翻转
//(1<=n<=1000)
#include <fstream>
#include <memory.h>
#include <iostream>
using namespace std;
#define N 7
int a[N][N];
int b[N][N];

void rotate( int s, int t, int x, int y ){
	int i, j;
	if( s == 1 ){	//顺时针
		for( i=0; i<t; i++ )
			for( j=0; j<t; j++ )
				b[x+j][y+t-1-i] = a[x+i][y+j];

		for( i=0; i<t; i++ )
			for( j=0; j<t; j++ )
				a[x+i][y+j] = b[x+i][y+j];

	}else{	//逆时针
		for( i=0; i<t; i++ )
			for( j=0; j<t; j++ )
				b[x+t-1-j][y+i] = a[x+i][y+j];

		for( i=0; i<t; i++ )
			for( j=0; j<t; j++ )
				a[x+i][y+j] = b[x+i][y+j];
		//for( i=0; i<t; i++ )
		//	b[x+t-1-i][y] = a[x][y+i];	//第1列
		//for( i=0; i<t; i++ )
		//	b[x+t-1-i][y+1] = a[x+1][y+i];	//第2列
		//for( i=0; i<t; i++ )
		//	b[x+t-1-i][y+2] = a[x+3][y+i];	//第3列
	}
};

int main()
{
	int i, j, k, n, m;
	int s, t, x, y, temp;
	ifstream cin("BUPT_1171.txt");//
	while( cin >> temp ){
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		a[0][0] = temp; 
		for( i=1; i<5; i++ )
			cin >> a[0][i];
		for( i=1; i<5; i++ )
			for( j=0; j<5; j++ )
				cin >> a[i][j];
		//for( i=0; i<5; i++ ){
		//	for( j=0; j<5; j++ )
		//		cout << a[i][j] << " ";
		//	cout << endl;
		//}
		cin >> s >> t >> x >> y;
		rotate( s, t, x-1, y-1 );
		for( i=0; i<5; i++ ){
			for( j=0; j<4; j++ )
				cout << a[i][j] << " ";
			cout << a[i][4] << endl;
		}
	}
	system("pause");//
	return 0;
}

九度OJ 题目1172:哈夫曼树
时间限制:1 秒  内存限制:32 兆  特殊判题:否  提交:618  解决:188
题目描述:
    哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。
输入:
    输入有多组数据。
    每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。
输出:
    输出权值。
样例输入:
    5  
    1 2 2 5 9
样例输出:
    37

刚从RE的深渊跳出来 又入了WA的苦海 有待未来解决了 暂时先这样吧 另外我的思路并不简洁 因为我把完整二叉树都创建出来了 总觉得应该有不需要建立完整二叉树就能求解的思路

说下我的思路吧:

首先创建树的节点结构体t[2000] 然后按照权值排序 只排序一次 之后先挑出最小的两个组队 生成和节点 并将和节点置于t[1000] 之后由于和节点和原节点两个序列都不为空 于是用findMin函数找到两个有序序列的最小两个权值节点 并返回其下标号 其中原节点无疑已经排序好 而和节点由题目性质是天然升序排列的 故只需设ti和hi两个推进指针 比较两序列最小值哪个更小即可 获得这对最小权值节点后

再用processNode函数生成这对节点合并产生的新和节点 并将这对节点的p[父指针]指向该和节点的序号 之后按层次遍历生成的赫夫曼数 算出每个节点所在的层数(对某节点的路径长度刚好为其所在层数 其中根节点层数为0)故只需再对t[0]~t[n-1]即原节点序列分别求带权路径长度 最后输出其加和WPL

//北邮2010网院:1172:哈夫曼树 
//(1<=n<=1000)
//注:除首轮外每轮结合的要么是t.h各一 要么2个h
//所有父节点都是h中的节点[即p都指向h中]
#include "StdAfx.h"
#include <fstream>
#include <algorithm>
//#include <ctime>
#include <iostream>
using namespace std;
struct NODE{
	int a;	//叶节点权值 不超过100
	int p, l, r;	//父.左.右节点序号 存储的是t[i]的i
	int depth;	//层数
	int index;
};
#define N 1000
NODE t[2*N]; //N之前记录原始节点 之后记录新生成的和节点 且和节点按生成顺序已然排序
int m[2];
int ti, hi, hl;	//ti.hi分别为原序列.和序列推进下标 依此找到2个min 而hl为新生成和元素下标
int b[2*N];	//遍历用

bool cmp( NODE x, NODE y ){
	return x.a < y.a;
};

void findMin( int &n ){	//寻找最小的2个节点
	for( int i=0; i<2; i++ ){
		if( hl==N ){	//和序列为空(和序列不可能用光)
			m[i] = ti;
			ti++;
		}else if( ti==n ){	//t用光
			m[i] = hi;
			hi++;
		}else{	//两序列都不空 从双序列中找最小值
			if( t[ti].a <= t[hi].a )
				{ m[i] = ti; ti++; }
			else
				{ m[i] = hi; hi++; }
		}
	}
};

void processNode( int x, int y ){	//x.y为节点index
	//创建新和节点:
	t[hl].a = t[x].a + t[y].a;
	t[hl].l = t[x].index;
	t[hl].r = t[y].index;
	t[hl].index = hl;
	t[x].p = t[y].p = hl;	//所有父节点都是h中的节点[即p都指向h中]
	hl++;	//下标处理
};

int main()
{
	int i, j, k, n;
	int WPL;
	ifstream cin("BUPT_1172.txt");//
	while( cin >> n ){
		//srand(time(NULL));	//初始化随机数生成器
		for( i=0; i<n; i++ ){
			cin >> t[i].a;
			//t[i].a = 90 + rand()%10;
			//t[i].a = n-i;
		}
		sort(t,t+n,cmp);
		//初始化:
		ti = 0;
		hi = N;	//当前待操作下标
		hl = N;	//hl为待写入新生成和元素的t[]的下标
		for( i=0; i<n; i++ ){
			t[i].index = i;
			t[i].l = t[i].r = t[i].p = -1;
		}

		for( i=0; i<n-1; i++ ){	//过2个产1个 每轮少1个待处理node 最终剩1个元素故n-1次
			findMin( n );
			//cout << "m:"<<m[0]<<"-"<<m[1]<<"  "<<"hi="<<hi<<" hl="<<hl<<endl;//
			processNode( m[0], m[1] );
		}
		
		t[hl-1].depth = 0;	//根节点是t[hl-1]
		//按层次遍历:
		b[0] = hl - 1;
		int p = 0;	//p=pointer
		int count = 0;
		for( i=0; i<2*n-1; i++ ){	//n个原节点(n-1)个和节点
			if( t[b[i]].l!=-1 ){
				p++;
				b[p] = t[b[i]].l;
			}
			if( t[b[i]].r!=-1 ){
				p++;
				b[p] = t[b[i]].r;
			}
			count++;
		}
		for( i=1; i<2*n-1; i++ ){
			t[b[i]].depth = t[t[b[i]].p].depth + 1;
		}
		
		for( i=0,WPL=0; i<n; i++ )
			WPL += t[i].a * t[i].depth;
		cout << WPL << endl;
	}
	system("pause");//
	return 0;
}


你可能感兴趣的:(c,null,System,存储,2010)