编程题总结(一)

目录

一、前言

二、题目和代码解答(都是C)

1、数组元素去重

 2、三除数

解题思路

3、你可以工作的最大周数

解题思路

4、收集足够苹果的最小花园周长

解题思路


一、前言

共四题、一题来自某个厂的前端夏令营笔试、三体来自leetcode周赛

二、题目和代码解答(都是C)

1、数组元素去重

题目要求很简单、就是输入数组然后输出去除重复的元素的新数组。

我本来想用C++来做但是发现了一些问题,要求的输入中是含有 ',' 这样的标点符号的,外加我本人c++太拉了,所以最终还是用了c语言完成

这道题的一个难点在于原地去重(tps:命题人没说要不要原地、经我自己的检验是要的)

如果不用原地去重,不妨可以使用一个排序将数组重新排序,然后比较相邻间元素是否相等即可。

以下是原地去重的C代码

#include<stdio.h>
#include<stdlib.h>


#define N 10000

int main(void)
{
	int nums[N], len = 0, x;
	while (scanf("%d", &x))
	{
		nums[len++] = x;
		// 嵌套循环遍历看新添加的是否已经和前面的数字重叠
		for (int i = 0; i < len - 1; i++)
		{
			// 如果重叠了就将长度减1,并跳出循环
			if (nums[i] == nums[len - 1])
			{
				--len;
				break;
			}
		}
		// 每次输入数字后面跟着逗号,如果没有则证明输入结束、跳出循环
		if (getchar() != ',')
		{
			break;
		}
	}
	for (int i = 0; i < len - 1; i++)
	{
		// 带逗号输出
		printf("%d,", nums[i]);
	}
	printf("%d\n", nums[len - 1]);

	return 0;
}

 2、三除数

就是给你一个整数n,如果n恰好用三个正除数,返回true,否则返回false。

链接https://leetcode-cn.com/problems/three-divisors/submissions/

解题思路

周赛第一题(装个*,这不是有hand就ok?)直接枚举,但是也可以做一下优化,比如枚举的范围,由于是除数,所以直接遍历到给定数的一半即可。另外考虑什么时候有三除数,就是三个因数、即除了1和数本身还有一个数,显然这个数的二次根式。



bool isThree(int n){
    int b = 0;
    for(int i = 2; i <= n/2; i ++)
    {
        if(n % i == 0)
        {
            if(i * i == n)
            {
                b = 1;
            }
            else
            {
                b = 0;
                break;
            }
        }
    }
    if(b)
    {
        return true;
    }
    return false;
}

3、你可以工作的最大周数

给你 n 个项目,编号从 0 到 n - 1 。同时给你一个整数数组 milestones ,其中每个 milestones[i] 表示第 i 个项目中的阶段任务数量。

你可以按下面两个规则参与项目中的工作:

每周,你将会完成 某一个 项目中的 恰好一个 阶段任务。你每周都 必须 工作。
在 连续的 两周中,你 不能 参与并完成同一个项目中的两个阶段任务。
一旦所有项目中的全部阶段任务都完成,或者仅剩余一个阶段任务都会导致你违反上面的规则,那么你将 停止工作 。注意,由于这些条件的限制,你可能无法完成所有阶段任务。

返回在不违反上面规则的情况下你 最多 能工作多少周。

链接https://leetcode-cn.com/problems/maximum-number-of-weeks-for-which-you-can-work/

解题思路

我所想到的思路其实是先将数组排序、然后统计除最大的数外的元素和然后与最大元素比较,如果和值比最大数大等于则返回总和值,理由是在实际操作中最大数是影响最终的周数的主要原因。一种常见的操作是最大数起手,然后与第二大的做反复横跳消减,重复这个操作。

以下是代码

int cmp(const void* a, const void* b)
{
    return *(int*)a - *(int*)b;
}

long long numberOfWeeks(int* milestones, int milestonesSize){
    if(milestonesSize == 1)
    {
        return 1;
    }
    int len = milestonesSize, *n = milestones;
    qsort(n, len, sizeof(int), cmp);
    int b = 0;
    long long sum = 0;
    for(int i = 0; i < len; i ++)
    {
        if(i == len - 1)
        {
            if(sum >= n[i])
            {
                b = 1;
            }
        }
        sum += n[i];
    }
    if(b)
    {
        return sum;
    }
    return 2 * (sum - n[len - 1]) + 1;
}

4、收集足够苹果的最小花园周长

这道题,作者实现了从0的突破,以前从来没有做出第三题的,有点小泪目。

给你一个用无限二维网格表示的花园,每一个 整数坐标处都有一棵苹果树。整数坐标 (i, j) 处的苹果树有 |i| + |j| 个苹果。

你将会买下正中心坐标是 (0, 0) 的一块 正方形土地 ,且每条边都与两条坐标轴之一平行。

给你一个整数 neededApples ,请你返回土地的 最小周长 ,使得 至少 有 neededApples 个苹果在土地 里面或者边缘上。

|x| 的值定义为:

如果 x >= 0 ,那么值为 x
如果 x < 0 ,那么值为 -x

链接:https://leetcode-cn.com/problems/minimum-garden-perimeter-to-collect-enough-apples/

解题思路

其实就是规律,当然这个规律要放到每一层去解读

这里就不推了。。。。(有点懒,困了)



long long minimumPerimeter(long long neededApples){
    long long c = 0, sum = 0, l;
    long long n = neededApples;
    for(int i = 0; ; ++ i)
    {
        l = 2 * (i + 1);
        c = 4 * l;
        sum += 6 *l + 6 * l * i;
        if(sum >= n)
        {
            break;
        }
    }
    return c;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值