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

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

1、翻转数列

小Q定义了一种数列称为翻转数列:
给定整数n和m, 满足n能被2m整除。对于一串连续递增整数数列1, 2, 3, 4…, 每隔m个符号翻转一次, 最初符号为’-‘;。
例如n = 8, m = 2, 数列就是: -1, -2, +3, +4, -5, -6, +7, +8.
而n = 4, m = 1, 数列就是: -1, +2, -3, + 4.
小Q现在希望你能帮他算算前n项和为多少。

输入描述:
输入包括两个整数n和m(2 <= n <= 109, 1 <= m), 并且满足n能被2m整除。

输出描述:
输出一个整数, 表示前n项和。

输入例子1:
8 2

输出例子1:
8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#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、纸牌游戏

牛牛和羊羊正在玩一个纸牌游戏。这个游戏一共有n张纸牌, 第i张纸牌上写着数字ai。
牛牛和羊羊轮流抽牌, 牛牛先抽, 每次抽牌他们可以从纸牌堆中任意选择一张抽出, 直到纸牌被抽完。
他们的得分等于他们抽到的纸牌数字总和。
现在假设牛牛和羊羊都采用最优策略, 请你计算出游戏结束后牛牛得分减去羊羊得分等于多少。

输入描述:
输入包括两行。
第一行包括一个正整数n(1 <= n <= 105),表示纸牌的数量。
第二行包括n个正整数ai(1 <= ai <= 109),表示每张纸牌上的数字。

输出描述:
输出一个整数, 表示游戏结束后牛牛得分减去羊羊得分等于多少。

输入例子1:
3 2 7 4

输出例子1:
5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#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

小Q的父母要出差N天,走之前给小Q留下了M块巧克力。小Q决定每天吃的巧克力数量不少于前一天吃的一半,但是他又不想在父母回来之前的某一天没有巧克力吃,请问他第一天最多能吃多少块巧克力

输入描述:
每个输入包含一个测试用例。
每个测试用例的第一行包含两个正整数,表示父母出差的天数N(N<=50000)和巧克力的数量M(N<=M<=100000)。

输出描述:
输出一个数表示小Q第一天最多能吃多少块巧克力。

输入例子1:
3 7

输出例子1:
4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#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的歌单

小Q有X首长度为A的不同的歌和Y首长度为B的不同的歌,现在小Q想用这些歌组成一个总长度正好为K的歌单,每首歌最多只能在歌单中出现一次,在不考虑歌单内歌曲的先后顺序的情况下,请问有多少种组成歌单的方法。

输入描述:
每个输入包含一个测试用例。
每个测试用例的第一行包含一个整数,表示歌单的总长度K(1<=K<=1000)。
接下来的一行包含四个正整数,分别表示歌的第一种长度A(A<=10)和数量X(X<=100)以及歌的第二种长度B(B<=10)和数量Y(Y<=100)。保证A不等于B。

输出描述:
输出一个整数,表示组成歌单的方法取模。因为答案可能会很大,输出对1000000007取模的结果。

输入例子1:
5 2 3 3 3

输出例子1:
9

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#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、安排机器

小Q的公司最近接到m个任务, 第i个任务需要xi的时间去完成, 难度等级为yi。
小Q拥有n台机器, 每台机器最长工作时间zi, 机器等级wi。
对于一个任务,它只能交由一台机器来完成, 如果安排给它的机器的最长工作时间小于任务需要的时间, 则不能完成,如果完成这个任务将获得200 * xi + 3 * yi收益。

对于一台机器,它一天只能完成一个任务, 如果它的机器等级小于安排给它的任务难度等级, 则不能完成。

小Q想在今天尽可能的去完成任务, 即完成的任务数量最大。如果有多种安排方案,小Q还想找到收益最大的那个方案。小Q需要你来帮助他计算一下。

输入描述:
输入包括N + M + 1行,
输入的第一行为两个正整数n和m(1 <= n, m <= 100000), 表示机器的数量和任务的数量。
接下来n行,每行两个整数zi和wi(0 < zi < 1000, 0 <= wi <= 100), 表示每台机器的最大工作时间和机器等级。
接下来的m行,每行两个整数xi和yi(0 < xi < 1000, 0 <= yi<= 100), 表示每个任务需要的完成时间和任务的难度等级。

输出描述:
输出两个整数, 分别表示最大能完成的任务数量和获取的收益。

输入例子1:
1 2
100 3
100 2
100 1

输出例子1:
1 20006

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;

struct Node {
int time, grade;
};

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

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

sort(machine.begin(), machine.end(), Cmp);
sort(task.begin(), task.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_grade = 101;
int min_j;
for (int j = 0; j < n; j++){
if (flag[j]){
if (task[i].time <= machine[j].time){
if (task[i].grade <= machine[j].grade && machine[j].grade < min_grade){
min_grade = machine[j].grade;
min_j = j;
}
}
else{
break;
}
}
}
if (min_grade != 101){
res++;
value += 200 * task[i].time + 3 * task[i].grade;
flag[min_j] = false;
}
}

delete[] flag;

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

return 0;
}

6、画家小Q

画家小Q又开始他的艺术创作。小Q拿出了一块有NxM像素格的画板, 画板初始状态是空白的,用’X’表示。
小Q有他独特的绘画技巧,每次小Q会选择一条斜线, 如果斜线的方向形如’/‘,即斜率为1,小Q会选择这条斜线中的一段格子,都涂画为蓝色,用’B’表示;如果对角线的方向形如’',即斜率为-1,小Q会选择这条斜线中的一段格子,都涂画为黄色,用’Y’表示。
如果一个格子既被蓝色涂画过又被黄色涂画过,那么这个格子就会变成绿色,用’G’表示。
小Q已经有想画出的作品的样子, 请你帮他计算一下他最少需要多少次操作完成这幅画。

输入描述:
每个输入包含一个测试用例。
每个测试用例的第一行包含两个正整数N和M(1 <= N, M <= 50), 表示画板的长宽。
接下来的N行包含N个长度为M的字符串, 其中包含字符’B’,’Y’,’G’,’X’,分别表示蓝色,黄色,绿色,空白。整个表示小Q要完成的作品。

输出描述:
输出一个正整数, 表示小Q最少需要多少次操作完成绘画。

输入例子1:
4 4
YXXB
XYGX
XBYY
BXXY

输出例子1:
3

例子说明1:
XXXX
XXXX
XXXX
XXXX
->
YXXX
XYXX
XXYX
XXXY
->
YXXB
XYBX
XBYX
BXXY
->
YXXB
XYGX
XBYY
BXXY

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#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、编码

假定一种编码的编码范围是a ~ y的25个字母,从1位到4位的编码,如果我们把该编码按字典序排序,形成一个数组如下: a, aa, aaa, aaaa, aaab, aaac, … …, b, ba, baa, baaa, baab, baac … …, yyyw, yyyx, yyyy 其中a的Index为0,aa的Index为1,aaa的Index为2,以此类推。 编写一个函数,输入是任意一个编码,输出这个编码对应的Index.

输入描述:
输入一个待编码的字符串,字符串长度小于等于100.

输出描述:
输出这个编码的index

输入例子1:
baca

输出例子1:
16331

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#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个,任务ID范围[1,1024]。请用32个unsigned int类型来记录着1024个任务是否已经完成。初始状态都是未完成。 输入两个参数,都是任务ID,需要设置第一个ID的任务为已经完成;并检查第二个ID的任务是否已经完成。 输出一个参数,如果第二个ID的任务已经完成输出1,如果未完成输出0。如果第一或第二个ID不在[1,1024]范围,则输出-1。

输入描述:
输入包括一行,两个整数表示人物ID.

输出描述:
输出是否完成

输入例子1:
1024 1024

输出例子1:
1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#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、素数对

给定一个正整数,编写程序计算有多少对质数的和等于输入的这个正整数,并输出结果。输入值小于1000。
如,输入为10, 程序应该输出结果为2。(共有两对质数的和为10,分别为(5,5),(3,7))

输入描述:
输入包括一个整数n,(3 ≤ n < 1000)

输出描述:
输出对数

输入例子1:
10

输出例子1:
2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>

using namespace std;

// 质数:只能被1和本身整除,最小质数为2
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转码。
此题考察纬度的二进制编码:算法对纬度[-90, 90]通过二分法进行无限逼近(取决于所需精度,本题精度为6)。注意,本题进行二分法逼近过程中只采用向下取整来进行二分,针对二分中间值属于右区间。算法举例如下: 针对纬度为80进行二进制编码过程:
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;

输入描述:
输入包括一个整数n,(-90 ≤ n ≤ 90)

输出描述:
输出二进制编码

输入例子1:
80

输出例子1:
111100

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#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、构造回文

给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。

输入描述:

输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.

输出描述:

对于每组数据,输出一个整数,代表最少需要删除的字符个数。

输入例子1:
abcda
google

输出例子1:
2 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#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、算法基础-字符移位

小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间。
你能帮帮小Q吗?

输入描述:

输入数据有多组,每组包含一个字符串s,且保证:1<=s.length<=1000.

输出描述:

对于每组数据,输出移位后的字符串。

输入例子1:
AkleBiCeilD

输出例子1:
kleieilABCD

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#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、有趣的数字

小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,相差最小的有多少对呢?相差最大呢?

输入描述:

输入包含多组测试数据。
对于每组测试数据:
N - 本组测试数据有n个数
a1,a2…an - 需要计算的数据
保证:
1<=N<=100000,0<=ai<=INT_MAX.

输出描述:

对于每组数据,输出两个数,第一个数表示差最小的对数,第二个数表示差最大的对数。

输入例子1:
6 45 12 45 32 5 6

输出例子1:
1 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#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、生成格雷码

在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同, 则称这种编码为格雷码(Gray Code),请编写一个函数,使用递归的方法生成N位的格雷码。

给定一个整数n,请返回n位的格雷码,顺序为从0开始。

测试样例:
1 返回:[“0”,”1”]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/*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、微信红包

春节期间小明使用微信收到很多个红包,非常开心。在查看领取红包记录时发现,某个红包金额出现的次数超过了红包总数的一半。请帮小明找到该红包金额。写出具体算法思路和代码实现,要求算法尽可能高效。

给定一个红包的金额数组gifts及它的大小n,请返回所求红包的金额。

若没有金额超过总数的一半,返回0。
测试样例:
[1,2,3,2,2],5
返回:2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Gift {
public:
/*
如果重复的次数超过一半的话,一定有相邻的数字相同这种情况的
对数组同时去掉两个不同的数字,到最后剩下的一个数就是该数字
*/
int getValue(vector<int> gifts, int n) {
int res = gifts[0], time = 1;
for(int i=1;i<gifts.size();i++){
if(gifts[i]==res) time++;
else{
time--;
if(time == 0){
res = gifts[i];
}
}
}
time = 0;
for(int i=0;i<gifts.size();i++){
if(gifts[i] == res) time++;
}
return time>gifts.size()/2?res:0;
}
};
0%