1.WY校招真题 不要二
描述
二货小易有一个W*H的网格盒子,网格的行编号为0~H-1,网格的列编号为0~W-1。每个格子至多可以放一块蛋糕,任意两块蛋糕的欧几里得距离不能等于2。
对于两个格子坐标(x1,y1),(x2,y2)的欧几里得距离为:
( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) 的算术平方根
小易想知道最多可以放多少块蛋糕在网格盒子里。
输入描述:
每组数组包含网格长宽W,H,用空格分割.(1 ≤ W、H ≤ 1000)
输出描述:
输出一个最多可以放的蛋糕数
示例1
输入:
3 2
输出:
4
本题的重点是要读懂题意,并且需要多读两遍,才能读懂,本题本质就是在二维数组中每个坐标去放蛋糕, 一个坐标位置放了蛋糕,跟他欧几里得距离为2的位置不能放蛋糕,这个就是关键点。对于两个格子坐标 (x1,y1),(x2,y2)的欧几里得距离为: ( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) 的算术平方根 。 也就是说:如果(x1,y1)放了蛋糕,则满足 ( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) == 4的(x2,y2)不能放蛋 糕。 ( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) == 4看起来是一个无解的表达式。 但是可以进行加法表达式分解: 1+3=4 3+1=4 2+2=4 0+4=4 4+0=4 仔细分析前三个表达式是不可能的,因为(x1-x2) * (x1-x2)表达式结果不能等于2或3。 也就是说( (x1-x2) * (x1-x2) 和(y1-y2) * (y1-y2) )两个表达式一个等于0,一个等于4. 可以看出:假设放蛋糕的位置是(x1,y1),则不能放蛋糕的位置(x2,y2),满足x1==x2,y1-y2==2或者x1- x2==2,y1==y2. 【解题思路】: 仔细读理解了上面的题目解读,本题就非常简单了,使用vector<vector>定义一个二维数组,resize开空间并初始化,每个位置初始化为1,表示当蛋糕,a[i][j]位置放蛋糕,则可以标记处a[i][j+2]和a[i+2][j]位置 不能放蛋糕,遍历一遍二维数组,标记处不能放蛋糕的位置,统计也就统计出了当蛋糕的位置数。
#include <iostream>
using namespace std;
#include<vector>
int main() {
int W = 0;
int H = 0;
cin >> W;
cin >> H;
int count = 0;
//分析可得x1=x2且y1-y2=2或-2;x1-x2=2或-2且y1-y2=0
vector<vector<int>> vv(H, vector<int>(W, 1));
for (int i = 0; i < vv.size(); i++) {
for (int j = 0; j < vv[0].size(); j++) {
if (vv[i][j] == 1) {
count++;
if (j + 2 < W)
vv[i][j + 2] = 0;
if (i + 2 < H)
vv[i + 2][j] = 0;
}
}
}
cout << count;
return 0;
}
2.字符串转成整数
描述
将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为 0 或者字符串不是一个合法的数值则返回 0
数据范围:字符串长度满足 0≤n≤100
进阶:空间复杂度 O(1) ,时间复杂度 O(n)
注意:
①字符串中可能出现任意符号,出现除 +/- 以外符号时直接输出 0
②字符串中可能出现 +/- 且仅可能出现在字符串首位。
输入描述:
输入一个字符串,包括数字字母符号,可以为空
返回值描述:
如果是合法的数值表达则返回该数字,否则返回0
示例1
输入:
"+2147483647"
返回值:
2147483647
示例2
输入:
"1a33"
返回值:
0
解题思路非常简单,就是上次计算的结果*10,相当于10进制进位,然后加当前位的值。 例如:“123”转换的结果是 sum=0 sum*10+1->1 sum*10+2->12 sum*10+3->123 本题的关键是要处理几个关键边界条件: 1. 空字符串 2. 正负号处理 3. 数字串中存在非法字符
class Solution {
public:
int StrToInt(string str)
{
if(str.empty())
return 0;
int symbol = 1;
if(str[0] == '-') //处理负号
{
symbol = -1;
str[0] = '0'; //这里是字符'0',不是0
}
else if(str[0] == '+') //处理正号
{
symbol = 1;
str[0] = '0';
}
int sum = 0;
for(int i=0;i<str.size();++i)
{
if(str[i] < '0' || str[i] > '9')
{
sum = 0;
break;
}
sum = sum *10 + str[i] - '0';
}
return symbol * sum;
}
};
3.Fibonacci数列
描述
Fibonacci数列是这样定义的:
F[0] = 0
F[1] = 1
for each i ≥ 2: F[i] = F[i-1] + F[i-2]
因此,Fibonacci数列就形如:0, 1, 1, 2, 3, 5, 8, 13, ...,在Fibonacci数列中的数我们称为Fibonacci数。给你一个N,你想让其变为一个Fibonacci数,每一步你可以把当前数字X变为X-1或者X+1,现在给你一个数N求最少需要多少步可以变为Fibonacci数。
输入描述:
输入为一个正整数N(1 ≤ N ≤ 1,000,000)
输出描述:
输出一个最小的步数变为Fibonacci数"
示例1
输入:
15
输出:
2
本题是对于Fibonacci数列的一个考察,Fibonacci数列的性质是第一项和第二项都为1,后面的项形成递归: F(n) = F(n - 1) + F(n - 2)。 本题可以通过先找到距离N最近的两个Fibonacci数,这两个数分别取自距离N的最近的左边一个数L和右边一 个数R,然后通过min(N - L, R - N)找到最小步数
#include <climits>
#include <iostream>
using namespace std;
#include<math.h>
int main() {
int N=0;
cin>>N;
int f0=0;
int f1=1;
int step=INT_MAX;
while(1)
{
int f=f0+f1;
f0=f1;
f1=f;
step=min(step,abs(N-f1));
if(step!=abs(N-f1))//step不再更新
break;
}
cout<<step;
}
4.合法括号序列判断
给定一个字符串A和其长度n,请返回一个bool值代表它是否为一个合法的括号串(只能由括号组成)。
测试样例:
"(()())",6
返回:true
测试样例:
"()a()()",7
返回:false
测试样例:
"()(()()",7
返回:false
【题目解析】: 本题考查的是对栈的应用 【解题思路】: 用栈结构实现,栈中存放左括号,当遇到右括号之后,检查栈中是否有左括号,如果有则出栈,如果没有, 则说明不匹配。
class Parenthesis {
public:
bool chkParenthesis(string A, int n) {
stack<char> s;
for(auto c:A)
{
if(c=='(')
s.push(c);
else if(c==')')
{
if(s.empty()||s.top()!='(')
{
return false;
}
else
s.pop();
}
}
if(s.empty())
return true;
else
return false;
// write code here
}
};