北京郵電大學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;
}


發佈了43 篇原創文章 · 獲贊 4 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章