2022-02-20每日刷题打卡

2022-02-20每日刷题打卡

力扣——每日一题

717. 1比特与2比特字符

有两种特殊字符:

第一种字符可以用一个比特 0 来表示
第二种字符可以用两个比特(10 或 11)来表示、
给定一个以 0 结尾的二进制数组 bits ,如果最后一个字符必须是一位字符,则返回 true 。

示例 1:

输入: bits = [1, 0, 0]
输出: true
解释: 唯一的编码方式是一个两比特字符和一个一比特字符。
所以最后一个字符是一比特字符。

一个个遍历,如果遍历到是0就遍历下一个(可以把它看成单字符),如果遇到1,就跳过下一个字符,如果跳过的下一个字符是最后一个字符,说明最后一个字符不能当作单字符,返回false。反之返回true。顺便可以一开始就判断一下最后一个字符是不是0,如果不是0那肯定不算单字符。

class Solution {
public:
    bool isOneBitCharacter(vector<int>& bits) {
        int n=bits.size();
        if(bits[n-1]!=0)return false;
        for(int i=0;i<n-1;i++)
        {
            if(bits[i]==0)
                continue;
            else
            {
                i++;
                if(i==n-1)return false;
            }
        }
        return true;
    }
};
6012. 统计各位数字之和为偶数的整数个数

给你一个正整数 num ,请你统计并返回 小于或等于 num 且各位数字之和为 偶数 的正整数的数目。

正整数的 各位数字之和 是其所有位上的对应数字相加的结果。

示例 1:

输入:num = 4
输出:2
解释:
只有 2 和 4 满足小于等于 4 且各位数字之和为偶数。

就这么写咯,遍历然后一个个判断数的各位和是否是偶数

class Solution {
public:
    bool get_num(int num)
    {
        int res = 0;
        string str = to_string(num);
        for (int i = 0; i < str.size();i++)
        {
            res += str[i] - '0';
        }
        if (res % 2 == 0)return true;
        return false;
    }
    int countEven(int num) {
        int n=num, res = 0;
        for (int i = 1; i <= n; i++)
        {
            if (get_num(i))
            {
                res ++;
            }
        }
        return res;
    }
};
6013. 合并零之间的节点

给你一个链表的头节点 head ,该链表包含由 0 分隔开的一连串整数。链表的 开端 和 末尾 的节点都满足 Node.val == 0 。

对于每两个相邻的 0 ,请你将它们之间的所有节点合并成一个节点,其值是所有已合并节点的值之和。然后将所有 0 移除,修改后的链表不应该含有任何 0 。

返回修改后链表的头节点 head 。

示例 1:

ex1-1.png (1203×83) (leetcode.com)

输入:head = [0,3,1,0,4,5,2,0]
输出:[4,11]
解释:
上图表示输入的链表。修改后的链表包含:

  • 标记为绿色的节点之和:3 + 1 = 4
  • 标记为红色的节点之和:4 + 5 + 2 = 11

遍历链表,计算非0节点的总和,如果遇到0节点且计算的总和不为0,就用总和创建一个节点,然后总和清零继续遍历链表。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeNodes(ListNode* head) {
        ListNode*p=head;
        ListNode*q=new ListNode();
        ListNode*m=q;
        int res=0;
        while(p!=NULL)
        {
            if(p->val!=0)
                res+=p->val;
            else
            {
                ListNode*o=new ListNode(res);
                res=0;
                q->next=o;
                q=q->next;
            }
            p=p->next;
        }
        if(res!=0)
        {
            ListNode*o=new ListNode(res);
            res=0;
            q->next=o;
            q=q->next;
        }
        return m->next->next;
    }
};
5996. 统计数组中相等且可以被整除的数对

给你一个下标从 0 开始长度为 n 的整数数组 nums 和一个整数 k ,请你返回满足 0 <= i < j < n ,nums[i] == nums[j] 且 (i * j) 能被 k 整除的数对 (i, j) 的 数目 。

示例 1:

输入:nums = [3,1,2,2,2,1,3], k = 2
输出:4
解释:
总共有 4 对数符合所有要求:

  • nums[0] == nums[6] 且 0 * 6 == 0 ,能被 2 整除。
  • nums[2] == nums[3] 且 2 * 3 == 6 ,能被 2 整除。
  • nums[2] == nums[4] 且 2 * 4 == 8 ,能被 2 整除。
  • nums[3] == nums[4] 且 3 * 4 == 12 ,能被 2 整除。

从左往右遍历数组,每次以一个地方为起点遍历数组,判断是否符合题目要求,满足则计数器++,最后返回计数器。

class Solution {
public:
    int countPairs(vector<int>& nums, int k) {
        int n=nums.size(),res=0;
        for(int i=0;i<n;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                if(nums[i]==nums[j]&&i*j%k==0)res++;
            }
        }
        return res;
    }
};
5997. 找到和为给定整数的三个连续整数

给你一个整数 num ,请你返回三个连续的整数,它们的 和 为 num 。如果 num 无法被表示成三个连续整数的和,请你返回一个 空 数组。

示例 1:

输入:num = 33
输出:[10,11,12]
解释:33 可以表示为 10 + 11 + 12 = 33 。
10, 11, 12 是 3 个连续整数,所以返回 [10, 11, 12] 。

计算一个平均数,如果是三个连续整数相加,那么这三个整数的平均数也是整数且平均数也是中位数,很简单的证明,三个连续的整数是:a-1,a,a+1,总和就是3a,平均数就是:3a/3=a,也是中间数a。

那么我们就直接对num/3,看得到的数是否是整数(但因为计算机的计算有问题,10/3这种的也会得到整数,此时我们把得到的除数*3看是否等于num即可),然后得到的数就是三个连续数的中位数,再依次把数存入数组里即可。

class Solution {
public:
    vector<long long> sumOfThree(long long num) {
        long long ans=num/3;
        vector<long long>v;
        if(ans*3==num)
            return {ans-1,ans,ans+1};
        return {}; 
    }
};
5998. 拆分成最多数目的偶整数之和

给你一个整数 finalSum 。请你将它拆分成若干个 互不相同 的偶整数之和,且拆分出来的偶整数数目 最多 。

比方说,给你 finalSum = 12 ,那么这些拆分是 符合要求 的(互不相同的偶整数且和为 finalSum):(2 + 10) ,(2 + 4 + 6) 和 (4 + 8) 。它们中,(2 + 4 + 6) 包含最多数目的整数。注意 finalSum 不能拆分成 (2 + 2 + 4 + 4) ,因为拆分出来的整数必须互不相同。
请你返回一个整数数组,表示将整数拆分成 最多 数目的偶整数数组。如果没有办法将 finalSum 进行拆分,请你返回一个 空 数组。你可以按 任意 顺序返回这些整数。

示例 1:

输入:finalSum = 12
输出:[2,4,6]
解释:以下是一些符合要求的拆分:(2 + 10),(2 + 4 + 6) 和 (4 + 8) 。
(2 + 4 + 6) 为最多数目的整数,数目为 3 ,所以我们返回 [2,4,6] 。
[2,6,4] ,[6,2,4] 等等也都是可行的解。

贪心解法,有两点:

一是要注意finalSum必须是偶数,毕竟一堆偶数绝不可能组合出一个奇数。

二是因为要求数目最多,所以我们从最小的偶数2开始组合,同样的finalSum,只要组合的数小,那数目就会多。

我们从2开始循环,每次加2,计算所有遍历过的数的总和,并且用哈希表记录下来,如果总和等于finalSum了结束循环,从哈希表里把用过的数全部取出来存入一个数组里返回。如果总和小于finalSum就继续算,如果大于了finalSum的话,就把总和和finalSum的差值的数去掉,比如finalSum是18,2+4+6+8=20,我们就把20-18=2去掉(在哈希表里,把那个数的出现次数减为0,这样在从哈希表里取数时就不会取到它了),最后就是4 6 8.然后因为减完后总和等于finalSum,我们就把用过的数都存入数组返回。

class Solution {
public:
    vector<long long>v;
    vector<long long> maximumEvenSplit(long long finalSum) {
        if(finalSum%2==1)return v;
        long long res=0;
        unordered_map<long long,int>mymap;
        for(int i=2;i<=finalSum;i+=2)
        {
            res+=i;
            if(res==finalSum)
            {
                mymap[i]++;
                break;
            }
            else if(res<finalSum)
            {
                mymap[i]++;
            }
            else if(res>finalSum)
            {
                mymap[i]++;
                mymap[res-finalSum]--;
                break;
            }
        }
        for(auto i:mymap)
        {
            if(i.second!=0)v.push_back(i.first);
        }
        return v;
    }
    
    
};

一本通——动态规划

1258:【例9.2】数字金字塔

【题目描述】

观察下面的数字金字塔。写一个程序查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以从当前点走到左下方的点也可以到达右下方的点。

img

在上面的样例中,从1313到88到2626到1515到2424的路径产生了最大的和8686。

【输入】

第一个行包含R(1≤R≤1000)R(1≤R≤1000),表示行的数目。

后面每行为这个数字金字塔特定行包含的整数。

所有的被供应的整数是非负的且不大于100100。

【输出】

单独的一行,包含那个可能得到的最大的和。

【输入样例】

5 
13 
11 8 
12 7  26 
6  14 15 8 
12 7  13 24 11

【输出样例】
86

我们从下往上走,每次取两个相邻数的最大值加到上一层,直到加到最顶上,那个就是可以得到的最大总和。

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<string.h>
#include<string>
#include<unordered_map>
#include<math.h>
#include<queue>

const int N = 1010;
int f[N][N],h[N][N];

int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j <= i; j++)
		{
			cin >> f[i][j];
		}
	}
	
	for (int i = n; i >=0 ; i--)
	{
		for (int j = 0; j < n; j++)
		{
			f[i][j] += max(f[i + 1][j], f[i + 1][j + 1]);
		}
	}
	cout << f[0][0] << endl;

	return 0;
}

1265:【例9.9】最长公共子序列

【题目描述】

一个给定序列的子序列是在该序列中删去若干元素后得到的序列。确切地说,若给定序列X=<x1,x2,…,xm>X=<x1,x2,…,xm>,则另一序列Z=<z1,z2,…,zk>Z=<z1,z2,…,zk>是X的子序列是指存在一个严格递增的下标序列<i1,i2,…,ik><i1,i2,…,ik>,使得对于所有j=1,2,…,k有:

Xij=ZjXij=Zj

例如,序列Z=<B,C,D,B>是序列X=<A,B,C,B,D,A,B>的子序列,相应的递增下标序列为<2,3,5,7>。给定两个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。例如,若X=<A,B,C,B,D,A,B>和Y=<B,D,C,A,B,A>,则序列<B,C,A>是X和Y的一个公共子序列,序列 <B,C,B,A>也是X和Y的一个公共子序列。而且,后者是X和Y的一个最长公共子序列.因为X和Y没有长度大于4的公共子序列。

给定两个序列X=<x1,x2,…,xm>X=<x1,x2,…,xm>和Y=<y1,y2….yn>Y=<y1,y2….yn>.要求找出X和Y的一个最长公共子序列。

【输入】

共有两行。每行为一个由大写字母构成的长度不超过1000的字符串,表示序列X和Y。

【输出】

第一行为一个非负整数。表示所求得的最长公共子序列的长度。若不存在公共子序列.则输出文件仅有一行输出一个整数0。

【输入样例】

ABCBDAB 
BDCABA
【输出样例】
4
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<string.h>
#include<string>
#include<unordered_map>
#include<math.h>
#include<queue>

const int N = 1010;
int f[N][N];

int main()
{
	string str1, str2;
	cin >> str1 >> str2;
	int n = str1.size(), m = str2.size();

	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
		{
			if (str1[i - 1] == str2[j - 1])f[i][j] = f[i - 1][j - 1] + 1;
			else f[i][j] = max(f[i - 1][j], f[i][j - 1]);
		}
	}
	cout << f[n][m];
	return 0;
}

蓝桥杯——历届真题

历届真题 成绩分析【第十一届】【省赛】【B组】

在这里插入图片描述

注意的地方就是输出两位小数。

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<string.h>
#include<string>
#include<unordered_map>
#include<math.h>
#include<queue>



int main()
{
	int n, min_score = INT_MAX, max_score = 0, num;
	double res = 0;
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> num;
		min_score=min(num, min_score);
		max_score = max(num, max_score);
		res += num;
	}
	cout << max_score << endl;
	cout << min_score << endl;
	res /= n;
	printf("%.2f", res );
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值