下午突然发现复试上机题在牛客上也有,花了快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 ;
}