# 技术类编程题汇总 C++ 刷题记录

14 篇文章 4 订阅
14 篇文章 3 订阅
7 篇文章 1 订阅

## 腾讯2018春招技术类编程题汇总

### 1、翻转数列

8 2

8

#include <iostream>
using namespace std;

// 暴力法 case通过率为80.00%，超时
long long fun(int n, int m) {
long long res = 0;
int k = 0, flag = -1;
for (int i = 0; i < n/m; i++){
for (int j = 0; j < m; j++){
k = flag * (abs(k) + 1);
res += k;
}
flag *= -1;
}
return res;
}

// 找规律：第一个加号值加上第一个减号值,差值刚好是m,共有n/2对
// -1, -2, +3, +4, -5, -6, +7, +8
long long fun2(int n, int m) {
return n/2*m;
}

int main() {
int n, m;
cin >> n >> m;

cout << fun2(n,m) << endl;
return 0;
}


### 2、纸牌游戏

3
2 7 4

5

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int main(){
int n;
cin >> n;
priority_queue<int, vector<int>,less<int>> card;
int t;
for (int i = 0; i < n; i++){
cin >> t;
card.push(t);
}

int res = 0;
int flag = 1;
while (!card.empty()){
int c = card.top();
res += flag*c;
flag *= -1;
card.pop();
}
cout << res << endl;
return 0;
}


### 3、贪吃的小Q

3 7

4

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

int fun(int n, int m){
int start = ceil(m / 2.0);
for (int i = start; i >= 1; i--){
int t = 0;
int ti = i;
for (int j = 0; j < n; j++){
t += ti;
if (ti != 1)
ti = ceil(ti / 2.0);
}
if (t <= m)
return i;
}
return 0;
}

int main(){
int n, m;
cin >> n >> m;

if (n == 1)
cout << m << endl;
else
cout << fun(n, m) << endl;
return 0;
}


### 4、小Q的歌单

5
2 3 3 3

9

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

// n选k组合数C(n,k) = C(n-1,k) + C(n-1,k-1）
void CreatSelect(vector<vector<long long>> &arr){
arr[0][0] = 1;
for (int i = 1; i <= 100; i++){
arr[i][0] = 1;
for (int j = 1; j <= 100; j++){
arr[i][j] = (arr[i - 1][j] + arr[i - 1][j - 1] )% 1000000007;
}
}
}

long long fun(int k, int a, int x, int b, int y, vector<vector<long long>> arr){
long long res = 0;
for (int i = 0; i <= k / a && i <= x; i++){
if ((k - a*i) % b == 0 && (k - a*i) / b <= y){
// x里选i个a，y里选(k - a*i) / b个b
res = (res + arr[x][i] * arr[y][(k - a*i) / b] % 1000000007) % 1000000007;
}
}
return res;
}

int main(){
int k;
cin >> k;
int a, b, x, y;
cin >> a >> x >> b >> y;

vector<vector<long long>> arr(101, vector<long long>(101));
CreatSelect(arr);

cout << fun(k, a, x, b, y, arr)  << endl;

return 0;
}


### 5、安排机器

1 2
100 3
100 2
100 1

1 20006

#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;

struct  Node {
};

bool Cmp(const Node &a, const Node &b) {
if (a.time == b.time)
return a.time > b.time;
}

// case通过率为90.00%，超时
int main() {
int n, m; //机器的数量和任务的数量 1 <= n, m <= 100000
cin >> n >> m;
vector<Node> machine(n);
for (int i = 0; i < n; i++){
}
for (int i = 0; i < m; i++){
}

sort(machine.begin(), machine.end(), Cmp);

int res = 0, value = 0;

bool* flag = new bool[n];
memset(flag, true, n);
for (int i = 0; i < m; i++){
int min_j;
for (int j = 0; j < n; j++){
if (flag[j]){
min_j = j;
}
}
else{
break;
}
}
}
res++;
flag[min_j] = false;
}
}

delete[] flag;

cout << res << " " << value << endl;

return 0;
}


### 6、画家小Q

4 4
YXXB
XYGX
XBYY
BXXY

3

XXXX
XXXX
XXXX
XXXX
->
YXXX
XYXX
XXYX
XXXY
->
YXXB
XYBX
XBYX
BXXY
->
YXXB
XYGX
XBYY
BXXY

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int n, m; //N和M(1 <= N, M <= 50), 表示画板的长宽
vector<vector<char>> arr;

void fun_b(int i, int j){
if (i >= 0 && i < n && j >= 0 && j < m && (arr[i][j] == 'B' || arr[i][j] == 'G')){
if (arr[i][j] == 'B')
arr[i][j] = 'X';
else
arr[i][j] = 'Y';
fun_b(i - 1,j + 1);
fun_b(i + 1, j - 1);
}
return;
}

void fun_y(int i, int j){
if (i >= 0 && i < n && j >= 0 && j < m && (arr[i][j] == 'Y' || arr[i][j] == 'G')){
if (arr[i][j] == 'Y')
arr[i][j] = 'X';
else
arr[i][j] = 'B';
fun_y(i + 1, j + 1);
fun_y(i - 1, j - 1);
}
return;
}

/*
YXXB
XYGX
XBYY
BXXY
*/

int fun() {
int res = 0;
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
if (arr[i][j] == 'B'){
fun_b(i, j);
res++;
}
if (arr[i][j] == 'Y'){
fun_y(i, j);
res++;
}
if (arr[i][j] == 'G'){
fun_b(i, j);
fun_y(i, j);
res += 2;
}
}
}
return res;
}

int main() {
cin >> n >> m;
arr = vector<vector<char>> (n, vector<char>(m));
string str;
for (int i = 0; i < n; i++){
cin >> str;
for (int j = 0; j < m; j++){
arr[i][j] = str[j];
}
}

cout << fun() << endl;

return 0;
}


## 腾讯2017秋招笔试编程题

### 1、编码

baca

16331

#include <iostream>
#include <vector>
#include <string>

using namespace std;

vector<int> loop = { 0, 1, 26, 651, 16276 };

int fun(string str) {
int res = 0, len = str.size();
for (int i = 0; i < len; i++){
res += (str[i] - 'a')*loop[4 -i]+1;
}
return res-1;
}

int main() {
string str;

while (cin >> str){
cout << fun(str) << endl;
}
return 0;
}


### 2、游戏任务标记

1024 1024

1

#include <iostream>

using namespace std;

unsigned int flag[32];

// unsigned int为32位，32个unsigned int为32*32=1024
int fun(int n, int m) {
// Index(N) = N / 32 = N >> 5;
// Position(N) = N % 32 = N & 31; （对于2的幂的数才能）
int index, position;
index = (n - 1) >> 5;
position = (n-1) & 31;
flag[index] |= 1 << position;
if (m >= 1 && m <= 1024){
index = (m - 1) >> 5;
position = (m - 1) & 31;
return (flag[index]&(1<<position))!=0;
}
return -1;
}

int main() {
int n,m;
cin >> n >> m;

cout << fun(n, m) << endl;
return 0;
}


### 3、素数对

10

2

#include <iostream>

using namespace std;

// 质数：只能被１和本身整除，最小质数为２
bool is_zhishu(int x) {
for (int i = 2; i*i <= x; i++){
if (x%i == 0)
return false;
}
return true;
}

int fun(int n) {
int res = 0;
for (int i = 2; i <= n / 2; i++){
if (is_zhishu(i) && is_zhishu(n - i))
res++;
}
return res;
}

int main() {
int n;
cin >> n;

cout << fun(n) << endl;
return 0;
}


### 4、geohash编码

geohash编码：geohash常用于将二维的经纬度转换为字符串，分为两步：第一步是经纬度的二进制编码，第二步是base32转码。

1. 区间[-90, 90]进行二分为[-90, 0),[0, 90]，成为左右区间，可以确定80为右区间，标记为1；
2. 针对上一步的右区间[0, 90]进行二分为[0, 45),[45, 90]，可以确定80是右区间，标记为1；
3. 针对[45, 90]进行二分为[45, 67),[67,90],可以确定80为右区间，标记为1；
4. 针对[67,90]进行二分为[67, 78),[78,90]，可以确定80为右区间，标记为1；
5. 针对[78, 90]进行二分为[78, 84),[84, 90]，可以确定80为左区间，标记为0；
6. 针对[78, 84)进行二分为[78, 81), [81, 84)，可以确定80为左区间，标记为0；

80

111100

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

// -66
string fun(int n) {
string res;
int k = 0;
int l = -90, r = 90;
while (k != 6){
int mid = floor((l + r) / 2.0);
if (mid <= n){
res.push_back('1');
l = mid;
}
else{
res.push_back('0');
r = mid;
}
k++;
}
return res;
}

string fun2(int n) {
string res;
int k = 0;
int l = -90, r = 90;
while (k != 6){
int mid = l + r > 0 ? floor((l + r) / 2.0) : -floor(-(l + r) / 2.0);
if (mid <= n){
res.push_back('1');
l = mid;
}
else{
res.push_back('0');
r = mid;
}
k++;
}
return res;
}

int main() {
int n; // (-90 ≤ n ≤ 90)
cin >> n;

cout << fun2(n) << endl;
return 0;
}


## 腾讯2017暑期实习生编程题

### 1、构造回文

abcda

2
2

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

// 求原字符串和其反串的最大公共子序列的长度
int fun(string s1, string s2) {
if (s1.size() == 1) return 1;
int len = s1.size();
vector<vector<int>> arr(len + 1, vector<int>(len + 1));
for (int i = 0; i <= len; i++){
for (int j = 0; j <= len; j++){
if (i == 0 || j == 0){
arr[i][j] =0;
}
else if (s1[i-1] == s2[j-1]){
arr[i][j] = arr[i - 1][j - 1] + 1;
}
else{
arr[i][j] = max(arr[i][j - 1], arr[i-1][j]);
}
}
}
return arr[len][len];
}

int main() {
string s; // 1 <= s.length <= 1000
while (cin >> s){
string s2 = s;
reverse(s2.begin(), s2.end());
cout << s.size()-fun(s,s2) << endl;
}

return 0;
}


### 2、算法基础-字符移位

AkleBiCeilD

kleieilABCD

#include <iostream>
#include <string>

using namespace std;

bool is_upper(char c){
return c >= 'A' && c <= 'Z';
}

string fun(string &s) {
if (s.size() == 1) return s;
for (int i = 0; i < s.size(); i++){
if (is_upper(s[i])){
for (int j = i + 1; j < s.size(); j++){
if (!is_upper(s[j])){
int  k = j;
char t = s[j];
while (k>i){
s[k] = s[k - 1];
k--;
}
s[i] = t;
break;
}
}
}
}
return s;
}

int main() {
string s; // 1 <= s.length <= 1000

while (cin >> s){
cout << fun(s) << endl;
}

return 0;
}


### 3、有趣的数字

N - 本组测试数据有n个数
a1,a2…an - 需要计算的数据

1<=N<=100000,0<=ai<=INT_MAX.

6
45 12 45 32 5 6

1 2

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

void fun(int n,vector<int> &vec) {
int min_count = 0, max_count = 0;
if (n > 1){
sort(vec.begin(), vec.end());
if (vec[0] == vec[n - 1]){ // 11111
min_count = n*(n - 1) / 2;
max_count = n*(n - 1) / 2;
}
else{
// min
int min = vec[1] - vec[0];
for (int i = 0; i < n - 1; i++){
if (vec[i + 1] - vec[i] < min){
min = vec[i + 1] - vec[i];
}
}
if (min == 0){ // 11233
int time;
for (int i = 0; i < n; i++){
time = 1;
while (i + 1 < n && vec[i + 1] == vec[i]){
time++;
i++;
}
min_count += time*(time - 1)/2;
}
}
else{ // 12457
for (int i = 0; i < n - 1; i++){
if (vec[i + 1] - vec[i] == min){
min_count++;
}
}
}

// max
int max = vec[n - 1] - vec[0];
int l = 0, r = 0;
for (int i = 0; i < n; i++){
if (vec[i] == vec[0]) l++;
else break;
}
for (int i = n - 1; i >= 0; i--){
if (vec[i] == vec[n-1]) r++;
else break;
}
max_count = l*r;
}
}
cout << min_count << " " << max_count << endl;
}

int main() {
int n;
while (cin >> n){
vector<int> vec(n);
for (int i = 0; i < n; i++){
cin >> vec[i];
}
fun(n, vec);
}

return 0;
}


## 腾讯2016研发工程师编程题

### 1、生成格雷码

1

/*n: 0   1    2     3
0   0   00   000
1   10   100
110
11  010
01
011
111
101
001
*/
class GrayCode {
public:
// 题目不严谨case通过率为9.09%
// 用例:2
// 对应输出应该为:["00","01","11","10"]
// 你的输出为:["00","10","11","01"]
vector<string> getGray2(int n) {
if (n == 0) return{ "0" };
vector<string> res{ "0", "1" };
for (int i = 1; i < n; i++){
for (int j = 0; j < res.size(); j++){
res[j].push_back('0');
}
for (int j = res.size()-1; j >=0; j--){
string t = res[j];
t[t.size() - 1] = '1';
res.push_back(t);
}
}
return res;
}
vector<string> getGray(int n) {
if (n == 0) return{ "0" };
vector<string> res{ "0", "1" };
for (int i = 1; i < n; i++){
for (int j = 0; j < res.size(); j++){
res[j]='0' + res[j];
}
for (int j = res.size()-1; j >=0; j--){
string t = res[j];
t[0] = '1';
res.push_back(t);
}
}
return res;
}
};


### 2、微信红包

[1,2,3,2,2],5

class Gift {
public:
/*
如果重复的次数超过一半的话，一定有相邻的数字相同这种情况的
对数组同时去掉两个不同的数字，到最后剩下的一个数就是该数字
*/
int getValue(vector<int> gifts, int n) {
int res = gifts[0], time = 1;
else{
time--;
if(time == 0){
}
}
}
time = 0;
}
}
};

• 0
点赞
• 9
收藏
觉得还不错? 一键收藏
• 0
评论
11-08
04-26
03-06
07-17
03-10 7790
05-20
11-05
12-05
10-17
01-26 1万+

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。