通过上一篇的继续学习,链接地址为:
https://blog.csdn.net/chao199512/article/details/83713409
接下来,我们继续讲解秋招笔试编程题,及其知识点总结。
(1)欢聚时代2018秋--------------计算重复字符串长度(点击文字进入链接)
题目解析
参考答案
方法一:
#include <bits/stdc++.h>
using namespace std;
int main(){
string s;
cin >> s;
int res = 0;// 最大子串长度
for(int i=0;i<s.size();++i){ //从第一个字符开始比较
for(int j=i+1;j<s.size();++j){ //遍历整个字符串
int len = 0; // 当前重复字符长度
int now = i; // 保存当前下表
int post = j; // 保存当前下表
while(s[now] == s[post]){
++now;
++post;
++len;
}
res = max(len,res);// 最大重复字串长度
}
}
printf("%d\n",res);
return 0;
}
方法二:
#include <iostream>
#include <string>
using namespace std;
int statLen(string str, int i, int j) {
int cur_len = 0;
while (i < str.size() && j < str.size() && str[i] == str[j]) {// 判断子串
i++;
j++;
cur_len++;
}
return cur_len;
}
int naiveLRS(string str) {
int maxlen = 0;
// 遍历所有字符串
for (int i = 0; i != str.size(); ++i) {
int len = 0;
for (int j = i + 1; j != str.size(); j++) {
len = statLen(str, i, j);// 获取子串长度
if (maxlen < len) { // 记录最大长度
maxlen = len;
}
}
}
return maxlen;
}
int main() {
string str;
cin >> str;
printf("%d", naiveLRS(str));
}
本题知识点:
(1)s.size()求出字符串的长度;
(2)使用now,post保存当前正在进行比较的下标;
(3)使用c++库中的函数max(数字1,数字2)求出了最大值。通过res对res进行替换,每次求得的都是当前字符串最大值。
(2)七牛云2018秋招---------------Young Tableau
题目描述
Young Tableau 是满足如下定义的二维数表:
- 所有行均为左对齐,所有行的最左端在同一列,且每一行均连续无空位;
- 从上到下每一行的列数非严格单调递减;
- 每一行中的数从左到右严格单调递增;
- 每一列中的数从上到下严格单调递增。
请编写一个程序,判断一个数表是否是Young Tableau。数表的行数和列数至多为10,所有数均为正整数。
-
是Young Tableau,而1 2 3 4 5 6
和1 3 2 4 5 6
都不是。1 4 5 2 3 6
- 输入格式:
每组测试数据包含多个测试点,输入的第一行表示测试点的数量(至多5 组)。
每个测试点是一个二维数表,输入中的每一行表示数表的一行,不同的数之间用一个空格隔开。 测试点之间用一个空行隔开。例如2 1 3 4 5 6 2 7 10 8 9 2 5 8 9 7 11 10
- 输出格式:
针对每一个测试点输出一行,内容为true/false(全部小写)表示是/不是Young Tableau。例如true false
-
题目解析
- 预备知识
- 严格递减表示
<
- 非严格递减表示
=<
- 不定长数据表示
- 【C方式】通常使用一个定长数组,非法数字表示行和列的结束。
- 【C++方式】使用嵌套
vector
。
- 严格递减表示
本题目就是二维循环简单遍历。
参考答案
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
bool IsYoungTableau(vector<vector<int>> nums){ //定义变长数组nums
if(nums.empty())return false;
for(int i=1;i!=nums.size();++i){
for(int j=1;j!=nums[i].size();++j){
// 右边的数必须大于左边的数
if (nums[i][j] < nums[i][j-1]) return false;
// 下边的数必须大于上边的数
if (nums[i][j] < nums[i-1][j]) return false;
}
// 当前行长度要小于等于上一行
if (nums[i].size() > nums[i-1].size()) return false;
}
return true;
}
int main(){
int n = 0;
scanf("%d\n",&n); // 这里\n防止被cin读入
bool res[n];
for(int i=0;i!=n;++i){
vector<vector<int> > nums;
string str; // 保存一行数据
while(getline(cin,str,'\n')){ // 读取一行数据
if(str.empty()) break; // 空行退出
istringstream iss(str);
int num = 0;
vector<int> temp;
while(iss >> num){ // 取出一行数据中的数字
temp.push_back(num);
}
nums.push_back(temp);
}
res[i] = IsYoungTableau(nums);
}
// 打印结果
for(int i=0;i!=n;++i){
cout << boolalpha << res[i] << endl;
}
}
本题知识点:
(1)定长数组与变长数组的定义;
(2)变长数组向量存储数据
vector<vector<int> > table;//定义一个二维变长数组table
vector<int> row1; //定义一个一维变长数组row1
row1.push_back(1); //向一维数组row1中插入值
row1.push_back(3);
row1.push_back(4);
row1.push_back(5);
row1.push_back(6);
vector<int> row2;
row2.push_back(2); //向一维数组row2中插入值
row2.push_back(7);
row2.push_back(10);
vector<int> row3; //向一维数组row3中插入值
row3.push_back(8);
row3.push_back(9);
table.push_back(row1); //将一维数组插入到二维数组中
table.push_back(row2);
table.push_back(row3);
(3) 对于变长数组而言:
table.size() //获取有多少行
table[i].size() //获取第i行有多少列
table[i] //获取第i行数据
table[i][j] //获取第i行第j列数据
(4)向量遍历
for(int i=0;i<table.size();++i){
for(int j=0;j<table[i].size();++j){
printf("%d ",table[i][j]);
}
printf("\n");
}
(3)吉比特2018秋招------------二进制个位不同个数(点击文字进入链接)
题目解析
-
预备知识
异或也叫半加运算,其运算法则相当于不带进位的二进制加法:二进制下用1表示真,0表示假,则异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位,所以异或常被认作不进位加法。
如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。 -
解题思路:
两个数进行异或,统计异或后的结果的二进制数1的个数,那么如何统计个数呢?有如下方法:将异或的结果与其减一进行与操作,直至与后的结果为零,就是二进制不同位数的数量。 -
实例解释
22
和33
进行异或。
- 十进制数 二进制数 a 22 10110 b 33 100001 ⊕ 55 110111 1
的个数,个数为5
。 -
参考答案
方法一:
#include <bits/stdc++.h>
using namespace std;
int main(){
int n = 0;
int m = 0;
scanf("%d%d",&n,&m);
int num = n^m;//进行异或操作
int count = 0;
while(num != 0){
if(num & 0x1) ++count; // 判断右端第一位是不是1
num = num>>1; // 右移一位
}
printf("%d\n",count);
}
方法二:
#include <bits/stdc++.h>
using namespace std;
int main(){
int n = 0;
int m = 0;
scanf("%d%d",&n,&m);
int num = n^m;
int count = 0;
while(num != 0){
++count;
num = (num-1)#// 每次去除1位
}
printf("%d\n",count);
}
本题知识点:
(1)输入的n,m为十进制数,但计算机本质是以二进制进行运算的,因此n,m可直接进行异或操作;
(2)这道题虽然代码很短,但思想很重要:通过(num-1)&num来统计结果值中1的个数。
(4)吉比特2018秋招-----------字母数字混合排序(点击文字进入链接)
题目解析
-
预备知识
sort(first,last)
以升序排序范围
[first, last)
中的元素。sort(first,last,cmp)
cmp(a,b)
比较函数,a
与b
不交换返回true
(也就是想要的顺序);first
与last
交换返回false
。 -
解题思路:
字符排序,判断条件追加字母与数字的区分(字母的ASCII码比数字大)。所以排序后的顺序为:数字|字母。因此我们可以将字符串数字部分进行截取,然后将数字部分追加到字母后边即可。 -
参考答案
方法一:
#include <bits/stdc++.h>
using namespace std;
int main(){
string s;
cin >> s;
sort(s.begin(),s.end());
int pos = 0;
for(int i=0;i<s.size();++i){
if(!('0'<=s[i] && s[i] <= '9')){
pos = i;
break;
}
}
// 截取数字部分
string num = s.substr(0,pos);
// 截取字母部分
string str = s.substr(pos);
cout << str+num;
return 0;
}
方法二:
#include <bits/stdc++.h>
using namespace std;
bool cmp(int a,int b){
// a 和 b一个是数字一个是字母
// '0' <= a && a <='9'
// 'a' <= b && b <='z'
if(isdigit(a) && isalpha(b)){
return false;
}
if(isdigit(b) && isalpha(a)){
return true;
}
// a 和 b都是数字或都是字母
return a < b;// 正确的顺序
}
int main() {
string s;
cin >> s;
sort(s.begin(),s.end(),cmp);
cout << s;
return 0;
}
方法三:冒泡排序
#include <bits/stdc++.h>
using namespace std;
int main(){
string str;
cin >> str;
for(int i=0;i!=str.size();++i){
for(int j=0;j!=str.size()-(i+1);j++){
if((str[j] <= '9' && str[j+1] >= 'a') ||
(str[j] > str[j+1] && str[j] <= '9') ||
(str[j] > str[j+1] && str[j+1] >= 'a')){
swap(str[j],str[j+1]);
}
}
}
cout << str << "\n";
}
本题知识点:
- 从
i
截取长度为len的
字符串s.substr(i,len);
- 从
i
截取到字符串结束s.substr(i);
- 字符串字典序排序
sort(s.begin(),s.end());
- 在字符串后添加
n
个字符c
s.append(n,c);
- 字符串连接
+
,str3 = str1+str2
- 构建一个
n
个字符c
组成的字符串string(n,c)
这里主要讲的就是排序问题,我们可以看下面的例子:
- 排序函数
sort(开始位置,结束位置)
- 按照
cmp
方式排序sort(开始位置,结束位置,cmp)
sort()
默认以字典序排列字符,以升序排列数字。
- 按照字典逆序排列字符串
#include <bits/stdc++.h>
using namespace std;
bool cmp(char a,char b) {
return a > b;// 正确的顺序
}
int main() {
string s; // s[i]
cin >> s;
sort(s.begin(),s.end(),cmp);
cout << s;
return 0;
}
- 按照降序排列数列
#include <bits/stdc++.h>
using namespace std;
bool cmp(int a,int b){
return a > b;// 正确的顺序
}
int main() {
int n = 0;
scanf("%d",&n);
int nums[n];
for(int i=0;i<n;++i){
scanf("%d",&nums[i]);
}
sort(nums,nums+n,cmp);
for(int i=0;i<n;++i){
printf("%d ",nums[i]);
}
return 0;
}
对数组进行排序,除了冒泡排序等,这也是一个不错的排序方式。
(5)百度2018秋招-------------字符覆盖(点击文字进入链接)
题目解析
先对两个字符串s和t元素从大到小进行排序,然后把t
按从大到小依次替换s
中小的字符,使得到的字符串s的字典序最大。
参考答案
#include <bits/stdc++.h>
using namespace std;
bool cmp(char a,char b){
return a>b; //正确的顺序
}
int main(){
string s ;
cin >> s;
string t ;
cin >> t;
sort(t.begin(),t.end(),cmp);
int j =0;
for(int i =0;i<s.size();i++){
while(j<t.size()){
if(s[i] <t[j]){
s[i]=t[j];
j++;
}else{
break;
}
}
}
cout << s;
return 0;
}
本题知识点:
这道题重点在对字符串通过函数cmp()进行逆向排序上,还有while()循环语句对替换条件的判定。相对简单,思维严密就好。
(6)拼多多2018秋招------------小熊吃糖(点击文字进入链接)
题目解析
需要用到排序算法:按战斗力对小熊们排序;按能填充的饥饿值对糖排序。
注意
- 最终答案需要按照小熊输入的顺序进行输出,在排序之后要记录一下这个信息。
- 一个小熊可能会吃多块糖
参考答案
方法一:
#include <bits/stdc++.h>
using namespace std;
// 小熊结构体
struct Bear{
int finger; // 战斗力
int hunger; // 饥饿值
int id; // 编号
};
bool cmpBear(Bear a,Bear b){
return a.finger > b.finger;
}
bool cmpBearById(Bear a,Bear b){
return a.id < b.id;
}
bool cmpSugar(int a,int b){
return a > b;
}
int main() {
int n = 0;// 小熊数量
int m = 0;// 糖数
scanf("%d%d",&n,&m);
int sugars[m];
for(int i=0;i<m;++i){
scanf("%d",&sugars[i]);
}
Bear bears[n];
for(int i=0;i<n;++i){
scanf("%d%d",&bears[i].finger,&bears[i].hunger);
bears[i].id = i; // 记录进入的顺序
}
// 糖果按照大小排序
sort(sugars,sugars+m,cmpSugar);
// 小熊按照战斗力排序
sort(bears,bears+n,cmpBear);
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
if(sugars[j] != 0 && bears[i].hunger >= sugars[j]){
// bears[i].hunger = bears[i].hunger - sugars[j];
bears[i].hunger -= sugars[j];
sugars[j] = 0;
}
}
}
sort(bears,bears+n,cmpBearById);// 按照进入顺序重新排序
for(int i=0;i<n;++i){
printf("%d\n",bears[i].hunger);
}
return 0;
}
方法二:
#include <bits/stdc++.h>
using namespace std;
// 小熊结构体
struct Bear{
int finger; // 战斗力
int hunger; // 饥饿值
int id; // 编号
};
struct Sugar{
int value; // 糖果数值
bool eated; // 是否被吃掉
};
bool cmpBear(Bear a,Bear b){
return a.finger > b.finger;
}
bool cmpBearById(Bear a,Bear b){
return a.id < b.id;
}
bool cmpSugar(Sugar a,Sugar b){
return a.value > b.value;
}
int main() {
int n = 0;// 小熊数量
int m = 0;// 糖数
scanf("%d%d",&n,&m);
Sugar sugars[m];
for(int i=0;i<m;++i){
scanf("%d",&sugars[i].value);
sugars[i].eated = false;
}
Bear bears[n];
for(int i=0;i<n;++i){
scanf("%d%d",&bears[i].finger,&bears[i].hunger);
bears[i].id = i; // 记录进入的顺序
}
// 糖果按照大小排序
sort(sugars,sugars+m,cmpSugar);
// 小熊按照战斗力排序
sort(bears,bears+n,cmpBear);
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
if(sugars[j].eated == false && bears[i].hunger >= sugars[j].value){
// bears[i].hunger = bears[i].hunger - sugars[j];
bears[i].hunger -= sugars[j].value;
sugars[j].eated = true;
}
}
}
sort(bears,bears+n,cmpBearById);// 按照进入顺序重新排序
for(int i=0;i<n;++i){
printf("%d\n",bears[i].hunger);
}
return 0;
}
本题知识点:
结构体
把多个变量绑到一起的一个类型,可以把结构体看成一个多个变量组成包。
struct 结构体{
变量...
};
例如:
定义结构体
struct UserInfo{
string name;
int age;
bool sex;
};
使用
UserInfo zhangsan;
zhangsan.name = "张三";
zhangsan.age = 31;
zhangsan.sex = true;
结构体数组
UserInfo users[n];
users[i].name
users[i].age
users[i].sex
本篇博客就到此结束了,当然,题目还有很多,如果有兴趣继续学习的话可看紧接的下一篇博客。
欢迎讨论互动,也可关注个人微信公众号“老凯运维”;毕竟运维工程师会开发路能够走的更远,开发会运维也是一个加分项。