牛客BUPT复试上机题

下午突然发现复试上机题在牛客上也有,花了快2h大概做了一下(基本都是模拟,应该是选的都是前两题
1

题目描述
大家都知道,数据在计算机里中存储是以二进制的形式存储的。 有一天,小明学了C语言之后,他想知道一个类型为unsigned int 类型的数字,存储在计算机中的二进制串是什么样子的。 你能帮帮小明吗?并且,小明不想要二进制串中前面的没有意义的0串,即要去掉前导0。

坑题,样例和数据不一致,不用输入T

#include 
using namespace std;
int main(){
	int a ;
	int T;
	//scanf("%d",&T) ; 
	while( ~scanf("%d",&a) ){
		if( !a ){ cout << 0 << endl; continue; }
		string res = "" ; 
		while( a ){
			res += ( a % 2 ) + '0'; 
			a /= 2 ; 
		} 
		for( int i = res.size() - 1 ; i >= 0 ; i-- ){
			cout << res[i] ; 
		}cout << endl;
	}
	return 0 ;  
}

题目描述
哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。

直接建树,层次遍历

#include 
using namespace std;
const int AX = 3e3 + 66 ;
struct Node{
	int x ; 
	int l , r ; 
	int id ; 
	Node(){}
	Node( int x , int l , int r , int id ):x(x),l(l),r(r),id(id){}
	bool operator < ( const Node &a )const{
		return x > a.x ; 
	}
}a[AX] ;
int main(){
	int n ;
	priority_queue<Node>q ; 
	while( ~scanf("%d",&n) ){
		for( int i = 0 ; i < n ; i++ ){
			scanf("%d",&a[i].x) ; 
			a[i].l = -1 ; a[i].r = -1 ; a[i].id = i ; 
			q.push(a[i]) ; 
		}
		int tot = n ; 
		while( q.size() > 1 ){
			Node u = q.top() ; q.pop() ; 
			Node v = q.top() ; q.pop() ;
			a[tot] = Node( u.x + v.x , u.id , v.id , tot ) ; 
			q.push(a[tot++]) ; 
		}
		int res = 0 ;
		int lev = 0 , c = 1 ;
		queue<Node>que ; que.push(q.top()) ; 
		while( !que.empty() ){
			int k = 0 ; 
			while( c-- ){
				Node t = que.front() ; 
				que.pop() ; 
				if( t.l == -1 && t.r == -1 ) res += t.x * lev ; 
				if( t.l != -1 ){que.push(a[t.l]); k++;}
				if( t.r != -1 ){que.push(a[t.r]); k++;}
			}
			lev++ ; 
			c = k ; 
		}
		cout << res << endl;
		while( !q.empty() ) q.pop() ; 
	}
	return 0 ;  
}

题目描述
第一行输入一个数,为n,第二行输入n个数,这n个数中,如果偶数比奇数多,输出NO,否则输出YES。

#include 
using namespace std;
const int AX = 1e3 + 66 ;
int x , n ; 
int main(){
	while( ~scanf("%d",&n) ){
		int even = 0 , odd = 0 ;
		for( int i = 0 ; i < n ; i++ ){
			scanf("%d",&x) ;
			if( x & 1 ) odd ++ ;
			else even ++ ;  
		}
		if( even > odd ) printf("NO\n");
		else printf("YES\n");
	}
	return 0 ;  
}

题目描述
查找一个数组的第K小的数,注意同样大小算一样大。 如 2 1 3 4 5 2 第三小数为3。

意思就是去重之后找第K小,排序+unique去重

#include 
using namespace std;
const int AX = 1e3 + 66 ;
int a[AX] ; 
int n , k ; 
int main(){
	while( ~scanf("%d",&n) ){
		for( int i = 0 ; i < n ; i++ ){
			scanf("%d",&a[i]) ; 
		}
		scanf("%d",&k) ; 
		sort( a , a + n ) ; 
		unique( a , a + n ) ; 
		cout << a[k-1] << endl;
	}
	return 0 ;  
}

题目描述
给定一个n*n的矩阵,求该矩阵的k次幂,即P^k。

#include 
#define LL long long  
using namespace std;
const int AX = 100 ; 
int n , k ;
struct Matrix{
	LL a[AX][AX] ; 
}ori , res;
Matrix mul( Matrix x , Matrix y ){
	Matrix c ; 
	memset( c.a , 0 , sizeof(c.a) ) ; 
	for( int i = 0 ; i < n ; i++ )
		for( int j = 0 ; j < n ; j++ )
			for( int k = 0 ; k < n ; k++ )
				c.a[i][j] += x.a[i][k] * y.a[k][j] ; 
	return c ; 
}

Matrix cal( int k ){
	while( k ){
		if( k & 1 ) res = mul( res , ori ) ; 
		k >>= 1 ; 
		ori = mul( ori , ori ) ; 
	}
	for( int i = 0 ; i < n ; i++ ){
		for( int j = 0 ; j < n ; j++ ){
			cout << res.a[i][j] << ' ' ; 
		}cout << endl;
	}
}

int main(){ 
	while( ~scanf("%d%d",&n,&k) ){
		for( int i = 0 ; i < n ; i++ ){
			for( int j = 0 ; j < n ; j++ ){
				res.a[i][j] = 0 ;
				cin >> ori.a[i][j] ; 
				if( i == j ) res.a[i][j] = 1 ; 
			}
		}
		cal(k) ; 
	}
	return 0 ;  
}

题目描述 牌只有1到9,手里拿着已经排好序的牌a,对方出牌b,用程序判断手中牌是否能够压过对方出牌。 规则:出牌牌型有5种 [1]一张
如4 则5…9可压过 [2]两张 如44 则55,66,77,…,99可压过 [3]三张 如444 规则如[2] [4]四张
如4444 规则如[2] [5]五张 牌型只有12345 23456 34567 45678 56789五个,后面的比前面的均大。

#include 
using namespace std;
const int AX = 1e3 + 66 ;
int b[AX] ;
string s , t ;
int lens , len ; 
bool solve(){
	len = t.size() ; 
	if( len == 1 || len == 5 ){
		lens = unique( b , b + lens ) - b ; 
		if( len == 1 ){
			if( b[lens-1] > (int)( t[0] - '0' ) ) return true ; 
		}  
		if( len == 5 ){
			for( int i = 0 ; i <= lens - 5 ; i++ ){
				if( b[i] > (int)( t[0] - '0' ) && b[i+4] == b[i] + 4 ) return true ; 
			}
		}
		return false ;
	}
	if( len > 1 && len < 5 ){
		for( int i = 0 ; i <= lens - len ; i++ ){
			if( b[i] > (int)( t[0] - '0' ) && b[i+len-1] == b[i] ) return true ; 
		}
		return false ; 
	}
} 
int main(){
	while( cin >> s >> t ){
		lens = s.size() ; 
		for( int i = 0 ; i < lens ; i++ ){
			b[i] = (int)( s[i] - '0' ) ; 
		}
		if( solve() ) cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	return 0 ;  
}

题目描述
有一棵树,输出某一深度的所有节点,有则输出这些节点,无则输出EMPTY。该树是完全二叉树。

完全二叉树性质

#include 
using namespace std;
const int AX = 1e3 + 66 ;
int n ; 
int a[AX] ; 
int main(){
	while( ~scanf("%d",&n) ){
		for( int i = 0 ; i < n ; i++ ){
			cin >> a[i] ; 
		}
		int d ;
		cin >> d ; 
		long long l = pow( 2 , d - 1 ) - 1 ;
		long long r = pow( 2 , d ) - 1 ;
		if( l < n && n > r ){
			for( int i = l ; i < r ; i ++ ){
				cout << a[i] ; 
				if( i != r - 1 ) cout << ' ' ; 
			}cout << endl;
		}else{
			cout << "EMPTY" << endl;
		}
	}
	return 0 ;  
}

题目描述
一个复数(x+iy)集合,两种操作作用在该集合上: 1、Pop 表示读出集合中复数模值最大的那个复数,如集合为空 输出 empty ,不为空就输出最大的那个复数并且从集合中删除那个复数,再输出集合的大小SIZE; 2 Insert a+ib 指令(a,b表示实部和虚部),将a+ib加入到集合中 ,输出集合的大小SIZE; 最开始要读入一个int n,表示接下来的n行每一行都是一条命令。

模拟,排序,字符串转数字

#include 
#define LL long long 
using namespace std;
const int AX = 1e3 + 66 ;
int n ;
struct Node{
	LL a , b , v ; 
	Node(){}
	Node( LL a , LL b , LL v ):a(a),b(b),v(v){}
	bool operator < ( const Node &x )const{
		return v < x.v ; 
	}
};
int main(){
	string op ; 
	priority_queue<Node>q;
	while( ~scanf("%d",&n) ){
		while( n-- ){
			cin >> op ; 
			if( op[0] == 'P' ){
				if( !q.size() ){
					printf("empty\n");
				}else{
					Node t = q.top() ; q.pop() ; 
					printf("%lld+i%lld\n",t.a,t.b);
					printf("SIZE = %d\n",q.size());
				}
			}else{
				cin >> op ; 
				int len = op.size() ;
				int a1 = 0 , b1 = 0 ; 
				string aa , bb ; 
				int i ; 
				for( i = 0 ; i < len ; i++ ){
					if( op[i] == '+' ){ i += 2 ; break ; }
					aa += op[i] ; 
				}
				for( ; i < len ; i++ ) bb += op[i] ; 
				if( aa.size() ){ a1 = atoi(aa.c_str()); }
				if( bb.size() ){ b1 = atoi(bb.c_str()); }

				long long v = 1LL * a1 * a1 + 1LL * b1 * b1 ; 
				//cout << a1 <<' ' << b1 << endl;
				q.push(Node(a1,b1,v)) ;
				printf("SIZE = %d\n",q.size());
			} 
		}
	}
	return 0 ;  
}

题目描述 第一行输入一个数n,1 <= n <= 1000,下面输入n行数据,每一行有两个数,分别是x y。输出一组x
y,该组数据是所有数据中x最小,且在x相等的情况下y最小的。

#include 
using namespace std;
const int AX = 1e3 + 66 ;
int n ;
struct Node{
	int x , y ;
	Node(){}
	Node( int x , int y ):x(x),y(y){}
	bool operator < ( const Node &a )const{
		if( x == a.x ) return y < a.y ;
		return x < a.x ; 
	}
}c[AX];
int main(){
	while( ~scanf("%d",&n) ){
		for( int i = 0 ; i < n ; i++ ){
			cin >> c[i].x >> c[i].y ; 
		}
		sort( c , c + n ) ; 
		cout << c[0].x << ' ' << c[0].y << endl ; 
	}
	return 0 ;  
}

题目描述
输入数组长度 n 输入数组 a[1…n] 输入查找个数m 输入查找数字b[1…m] 输出 YES or NO 查找有则YES 否则NO 。

#include 
using namespace std;
int n , x ;
map<int,int>mp ; 
int main(){
	while( ~scanf("%d",&n) ){
		mp.clear() ; 
		for( int i = 0 ; i < n ; i++ ){
			cin >> x ; mp[x] = 1 ; 
		}
		int m ;
		cin >> m ; 
		for( int i = 0 ; i < m ; i++ ){
			cin >> x ; 
			cout << ( mp[x] ? "YES" : "NO" ) << endl;
		}
	}
	return 0 ;  
}

你可能感兴趣的:(牛客BUPT复试上机题)