2022 阿里笔试第一场,算法题

第一题

很简单随便写

第二题

给一个整数N(3<=N<=10^7),求正N多边形中有多少个等腰锐角三角形。
实例:N=3
答案:1
实例:N=4
答案:0
实例:N=5
答案:5

以下给出两种解法:

  1. 暴力法 O(N)
    从一个点A出发,同时向两侧移动,两侧点分别为B和C,AB和AC组成等腰边,BC组成底边。
    当BAC占有正N多边形的边数大于BC占有的边数时,ABC组成等腰锐角三角形。
    cnt 开始计数,并继续逐个点移动,直到BC点重合。
    特殊情况:当ABC组成等边三角形时,另外两个点计算时会有重复的结果,因此需额外判断N是不是三的倍数
    因此有:res = cnt*N - (N/3*2 if N%3 == 0 else 0)
  2. 数学法 O(1)
    简单的把暴力法转换为数学法。
    minAB = minAC = N/4 + 1 :等腰边最小跨过的N边形边数
    maxBC = N - minAB - minAC = N - (N/4 + 1) * 2 :底边最长的长度
    因此 底边长度可以为以下值
    maxBC, maxBC-2, maxBC-4 … 1 :当maxBC%2 == 1
    maxBC, maxBC-2, maxBC-4 … 2 :当maxBC%2 == 0
    所以有
    cnt = ceil( (N - (N/4 + 1) * 2) / 2)
    同时考虑特殊情况:当ABC组成等边三角形时,另外两个点计算时会有重复的结果,因此需额外判断N是不是三的倍数
    因此有:res = cnt*N - (N/3*2 if N%3 == 0 else 0)
#include <iostream>
#define LL long long
using namespace std;

LL ViolenceToSolve(int N)
{
   
    LL res = 0;
    LL cnt = 0;
    for(int i=1; i<=N/2; ++i)
    {
   
        if(N-i*2>0 && N-i*2<i*2)
        {
   
            ++cnt;
        }
    }
    res = cnt*N;
    if(N%3 == 0)
    {
   
        res -= N/3*2;
    }
    return res;
}

LL MathToSolve(int N)
{
   
    LL res = 0;
    LL cnt = 0;
    cnt = N - (N/4*2+2);//底边maxBC
    cnt = cnt/2 + cnt%2;//ceil操作
    res = cnt*N;
    if(N%3 == 0)
    {
   
        res -= N/3*
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值