【牛客网】—— 2017年校招真题2

上次整理2017年校招真题中的一些题目 2017年校招真题 今天继续更新一些。

2017年校招真题2

题目ID:45844 --两种排序方法

题目描述

考拉有n个字符串字符串,任意两个字符串长度都是不同的。考拉最近学习到有两种字符串的排序方法: 1.根据字符串的字典序排序。例如:“car” < “carriage” < “cats” < "doggies < “koala”
2.根据字符串的长度排序。例如:“car” < “cats” < “koala” < “doggies” < “carriage”
考拉想知道自己的这些字符串排列顺序是否满足这两种排序方法,考拉要忙着吃树叶,所以需要你来帮忙验证。
输入描述:

输入第一行为字符串个数n(n ≤ 100) 接下来的n行,每行一个字符串,字符串长度均小于100,均由小写字母组成

输出描述:

如果这些字符串是根据字典序排列而不是根据长度排列输出"lexicographically",
如果根据长度排列而不是字典序排列输出"lengths",
如果两种方式都符合输出"both",否则输出"none"

示例1

输入:3
a
aa
bbb
输出:both

解题思路

  • 不要看题目很长就觉得很难,其实思路还是很简单的,我们在接收数据的时候,用vector存储3份数据,之后通过sort排序,将第二份数据按照长度排序,将第三份数据按照字典排序,之后比较第一份数据和第二第三份数据的异同,并按照要求输出对应的字符串即可。
    sort的用法

代码实现

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

using namespace std;
bool length(string& a,string& b)
{
    return a.size() < b.size();
}
bool dict(string& a,string& b)
{
    return a < b;
}

int main()
{
    int n;
    cin >> n;
    vector<string> vs,vl,vd;
    string str;
    for(int i = 0;i < n;++i)
    {
        cin >> str;
        vs.push_back(str);
        vl.push_back(str);
        vd.push_back(str);
    }
    sort(vl.begin(),vl.end(),length);
    sort(vd.begin(),vd.end(),dict);
    if(vs == vl&&vs == vd)
        cout << "both" << endl;
    else if(vs == vl)
        cout << "lengths" << endl;
    else if(vs == vd)
        cout << "lexicographically" << endl;
    else
        cout << "none" << endl;
    return 0;
}

题目ID:36932 - 求最小公倍数

题目描述

正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数。

输入描述:

输入两个正整数A和B。

输出描述:

输出A和B的最小公倍数。

示例1

输入:5 7
输出:35

解题思路

  • 这个思路就比较简单了,代码实现也很简单,其实我们都应该知道两个数最小公倍数等于二者的乘积除以两者的最大公约数,所以我们先利用辗转相除法求出两数的最大公约数,再用两数乘积一除就可以了。

代码实现

#include <iostream>
using namespace std;
int main()
{
	int A, B;
	cin >> A >> B;
	int C = A * B;
	int tmp;
	while (A)
	{
		tmp = A;
		A = B % A;
		B = tmp;
	}
	cout << C / B << endl;
	return 0;
}

题目ID:25083 – 另类加法

题目描述

请编写一个函数,将两个数字相加。不得使用+或其他算数运算符。
给定两个int A和B。请返回A+B的值

测试样例:

输入:1,2
返回:3

解题思路

  • 代码实现是比较简单的,但是有一点难想到该种方法,还有一些难理解,下面详细讲一下
  • 本题可以通过位运算实现,具体实现如下:
  1. 二进制位异或运算相当于对应位相加,不考虑进位
    比如: 1 ^ 1 = 0 —> 1 + 1 = 0 (当前位值为0,进一位)
    1 ^ 0 = 1 —> 1 + 0 = 1 (当前位值为1)
    0 ^ 0 = 0 —> 0 + 0 = 0 (当前位值为0)
  2. 二进制位与运算相当于对应位相加之后的进位
    比如: 1 & 1 = 1 —> 1 + 1 = 0 (当前位的值进一位)
    1 & 0 = 0 —> 1 + 0 = 1 (当前位的值不进位)
    0 & 0 = 0 —> 0 + 0 = 0 (当前位的值不进位)
  3. 两个数相加:对应二进制位相加的结果 + 进位的结果
    比如:3 + 2 --> 0011 + 0010 --> 0011 ^ 0010 + ((0011 & 0010) << 1)
    —> (0011 ^ 0010) ^ ((0011 & 0010) << 1), 当进位之后的结果为0时,相加结束

代码实现

class UnusualAdd {
public:
	int addAB(int A, int B) {
		int sum = 0, carry = 0;
		while (B != 0){
			//对应位的和
			sum = A^B;
			//对应位和的进位,既然是进位,就要整体左移一位
			carry = (A&B) << 1;
			A = sum;
			B = carry;
		}
		return sum;
	}
};

题目ID:36915-求路径总数

题目描述

请编写一个函数(允许增加子函数),计算n x m的棋盘格子(n为横向的格子数,m为竖向的格子数)沿着各自边缘线从左上角走到右下角,总共有多少种走法,要求不能走回头路,即:只能往右和往下走,不能往左和往上走。
输入描述:

输入两个正整数

输出描述:

返回结果

解题思路

用递归来做,将右下角看做原点(0,0),左上角看做坐标(m,n),下图所示:

从(m,n) - >(0,0)就分两步走:
往右走一步:f(m,n - 1) - >(0,0)加上下走一步:f(m - 1,n) - >(0,0)
注意:但凡是触碰到边界,也就是说f(x,0)或者f(0,x)都只有一条直路可走了,这里的x是变量哈。
f(m,n)= f(m,n - 1)+ f(m - 1,n)

代码实现

#include <iostream>
 
using namespace std;
 
int func(int m, int n) {
    if (m == 0 || n == 0) {
        return 1;
    }
    return func(m, n - 1) + func(m - 1, n);
}
int main() {
    int m, n;
    while (cin >> m >> n) {
        cout << func(m, n) << endl;
    }
 
    return 0;
}
发布了167 篇原创文章 · 获赞 175 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chenxiyuehh/article/details/90732073