3.19 OJ打卡练习

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
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值