牛客网--今日头条2017后端工程师实习生笔试题

牛客网--今日头条2017后端工程师实习生笔试题

[编程题]最大映射

有 n 个字符串,每个字符串都是由 A-J 的大写字符构成。现在你将每个字符映射为一个 0-9 的数字,不同字符映射为不同的数字。这样每个字符串就可以看做一个整数,唯一的要求是这些整数必须是正整数且它们的字符串不能有前导零。现在问你怎样映射字符才能使得这些字符串表示的整数之和最大?

输入描述:

每组测试用例仅包含一组数据,每组数据第一行为一个正整数 n , 接下来有 n 行,每行一个长度不超过 12 且仅包含大写字母 A-J 的字符串。 n 不大于 50,且至少存在一个字符不是任何字符串的首字母。

输出描述:

输出一个数,表示最大和是多少。

示例1

输入

2
ABC
BCA

输出

1875
#include <cstdio> 
#include <cstdlib> 
#include <cstring> 
#include <cmath> 

#include <iostream> 
using namespace std; 
const int MAXN = 55; 

struct Node{
	unsigned long long num;
	int head;  
}nd[10]; 

int cmp(const void *a, const void *b){
	Node* aa = (Node *)a; 
	Node* bb = (Node *)b; 
	if(aa->num > bb->num){
		return -1; 
	}else{
		return 1; 
	}
}
int main(){
	int n, len, jdx;
	unsigned long long idx, ans;  
	char ch[MAXN][20]; 
	while(scanf("%d", &n) != EOF){
		for(int i=0; i<10; ++i){
			nd[i].num = 0; 
			nd[i].head = 0; 
		}
		for(int i=0; i<n; ++i){
			getchar(); 
			scanf("%s", ch[i]); 
			len = strlen(ch[i]); 
			idx = 1; 
			for(int j=len-1; j>=0; --j){
				nd[ ch[i][j] - 'A' ].num += idx; 
				if( j == 0 ){
					nd[ ch[i][j] - 'A' ].head = 1; 
				}
				idx *= 10; 
			}
		}
		qsort(nd, 10, sizeof(nd[0]), cmp); 

		jdx = -1; 
		for(int i=9; i>=0; --i){
			if(nd[i].head == 0){
				jdx = i; 
				break; 
			}
		}
		idx = 9;  ans = 0; 
		for(int i=0; i<10; ++i){
			if(i == jdx){
				continue; 
			}
			ans += idx * nd[i].num; 
			--idx; 
		}
		printf("%lld
", ans );
	}
	return 0; 
}

  

[编程题]木棒拼图

有一个由很多木棒构成的集合,每个木棒有对应的长度,请问能否用集合中的这些木棒以某个顺序首尾相连构成一个面积大于 0 的简单多边形且所有木棒都要用上,简单多边形即不会自交的多边形。

初始集合是空的,有两种操作,要么给集合添加一个长度为 L 的木棒,要么删去集合中已经有的某个木棒。每次操作结束后你都需要告知是否能用集合中的这些木棒构成一个简单多边形。

输入描述:

每组测试用例仅包含一组数据,每组数据第一行为一个正整数 n 表示操作的数量(1 ≤ n ≤ 50000) , 接下来有n行,每行第一个整数为操作类型 i (i ∈ {1,2}),第二个整数为一个长度 L(1 ≤ L ≤ 1,000,000,000)。如果 i=1 代表在集合内插入一个长度为 L 的木棒,如果 i=2 代表删去在集合内的一根长度为 L 的木棒。输入数据保证删除时集合中必定存在长度为 L 的木棒,且任意操作后集合都是非空的。

输出描述:

对于每一次操作结束有一次输出,如果集合内的木棒可以构成简单多边形,输出 "Yes" ,否则输出 "No"。

示例1

输入

5
1 1
1 1
1 1
2 1
1 2

输出

No
No
Yes
No
No
#include <cstdio> 
#include <vector> 
#include <queue> 
#include <iostream> 
using namespace std; 

int main(){
	int n, op, max_v, num; 
	long long sum;  
	while(scanf("%d", &n) != EOF){
		priority_queue<int> qt;  
		sum = 0;
		for(int i=0; i<n; ++i){
			scanf("%d %d", &op, &num); 
			if(op == 1){
				qt.push( num );  
				sum += num; 
			}else{
				vector<int> tmp; 
				while(qt.top() != num){
					tmp.push_back( qt.top() ); 
					qt.pop(); 
				}
				qt.pop(); 
				for(int i=0; i<tmp.size(); ++i){
					qt.push( tmp[i] ); 
				}
				sum -= num;  
			}
			if(sum > 2*qt.top()){
				printf("Yes
");
			}else{
				printf("No
");
			}
		}
	} 
	return 0; 
}

  

给定 x, k ,求满足 x + y = x | y 的第 k 小的正整数 y 。 | 是二进制的或(or)运算,例如 3 | 5 = 7。

比如当 x=5,k=1时返回 2,因为5+1=6 不等于 5|1=5,而 5+2=7 等于 5 | 2 = 7。

#include <iostream>
using namespace std;
const int MAXN = 64;
 
int main(){
 
    long long n,k, ans, vt[MAXN];
    while(scanf("%lld %lld", &n, &k) != EOF){
        int cnt = 0;
        for(int i=0; i<MAXN; ++i){
            long long cur = ((long long)1) << i;
            if( (n & cur) == 0){
                vt[cnt++] = cur;
            }
        }
        int j = 0;
        ans = 0;
        while(k > 0){
            if( (k & 1) != 0){
                ans += vt[j];
            }
            ++j;
            k = k >> 1;
        }
        printf("%lld
", ans );
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/zhang-yd/p/7458708.html