複試上機題目練習


個人準備複試上機時,遇到的題,方便之後鞏固

上機練習題型

全排列

運用遞歸方法,對n個數進行全排列:
(若要求對n個字母進行全排列,p[]類型可改爲char,原代碼中p[index]=i可改爲p[idex] = i+‘a’-1或p[index] = i+‘A’-1)

#include<iostream>
using namespace std;

const int maxn = 11;
//p爲當前排列,hashTable記錄整數x是否已經在p中
int nn,p[maxn],hashTable[maxn] = {false};
//當前處理排列的第index位
void generateP(int index){
	int i= 1;
	if(index == nn+1){//遞歸邊界,已經處理完排列的1~n位
		for(i = 1;i<=nn;i++){
			cout<<p[i];  //輸出全排列
		}
		cout<<endl;
		return ;
	}else{
		for(i = 1;i<=nn;i++){
			if(hashTable[i]==false){  //處理不在p中的
				p[index] = i;        //i加入當前序列
				hashTable[i] = true;  //修改標記
				generateP(index+1);    //處理第index+1位
				hashTable[i]=false;   //遞歸的下邊處理完了,返回到這裏,還原狀態
			}
		}
	}
}
int main(){
	nn = 3;
	generateP(1); //從1開始
	return 0;
}

運行結果

哈夫曼樹最小帶權路徑

輸入:
4
1,1,1,1
輸出:最小帶權路徑
大體思路:建立小頂堆,將輸入的頂點入堆,再每次取出堆中兩個最小的元素即堆頂,作爲左右孩子節點,將他們的和作爲雙親,再放回堆中,如此反覆。直到堆中只剩一個節點。

#include<iostream>
#include<queue>
using namespace std;
priority_queue<int,vector<int>,greater<int> > que;//優先隊列.小頂堆

void main20192(){
	char a;
	int n,i = 0,num;
	while(cin>>n){
		while(que.empty()==false)que.pop();//清空堆中元素
		//輸入   以,隔開
		for(i=1;i<=n;i++)
		{
			cin>>num;
			que.push(num);
			if(i!=n)cin>>a;//吸收最後一個回車
		} 
		int sum = 0;
		while(que.size()>1){
			//取出堆中兩個最小的元素,作爲同一節點的左右孩子,且雙親的權值是他們的和
			int a = que.top();
			que.pop();
			int b = que.top();
			que.pop();

			sum += a+b;//該父親節點必爲非葉子結點,累加
			que.push(a+b);//雙親的權值放回堆中
		}
		cout<<sum<<endl;
	}
}
int main(){
	main20192();
	return 0;
}

已知先序序列,中序序列求後序序列

先序的第一個字符爲根節點,再去中序中找根節點的位置,並以此切分,得到左右子樹的序列。左右子樹再同理。此方法並沒有建立出樹,只是對字符串的劃分

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

typedef struct BTNode{
	char val;
	struct BTNode *left;
	struct BTNode *right;
}BTnode;

int index = 0;
//核心代碼
void getTree(string front,string mid){
	if(mid.length() == 0)
		return ;

	char root = front[index ++];//index每次遞歸加一,用以獲取先序中的下一個根字符

	int i = mid.find(root);  //找到根在中序中的位置

	//切分中序序列,得到左右兩部分
	string left = mid.substr(0,i);
	string right = mid.substr(i+1,mid.length()-1);

	//後序遍歷:左右根
	getTree(front,left);  //繼續遞歸左邊
	getTree(front,right);  //遞歸右邊
	cout<<root;
}
void wangdao3334(){
	string front;
	string mid;
	cout<<"先序遍歷:";
	cin>>front;
	cout<<"中序遍歷:";
	cin>>mid;
	getTree(front,mid);
}

int main(){
	wangdao3334();
	return 0;
}

求一個數的m進制

#include<iostream>
using namespace std;

/** 輸入num1,num2,求和的m進制,m<=16 */
void wangdao4342(){
	char num[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

	int m,num1,num2;
	cin>>m>>num1>>num2;

	int sum = num1+num2;
	char a[10],index = 0;
	while(sum!=0){
		a[index ++] = num[sum%m];//餘數。主要是爲了處理餘數大於10的情況
		sum /= m;  //繼續求下一位
	}

	for(m = index-1;m>=0;m--){
		cout<<a[m];  //倒着輸出
	}
	cout<<endl;
}
int main(){
	wangdao4342();
	return 0;
}

未完待續

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章