杂题部分

news/2024/11/9 0:01:44/文章来源:https://www.cnblogs.com/mumujun12345/p/18536141

杂题部分

  1. 3131. 找出与数组相加的整数 I

思路

快排+直接找差值。

void quickSort(int *arr,int low,int high)
{if(high<=low) return;int i=low;int j=high;int pivot=arr[low];while(1){// 1. 自左到右搜索,直到比pivot大后停止。while(arr[i]<=pivot){i++;if(i==high) break;}// 2. 自右到左搜索,直到比pivot小后停止。while(arr[j]>=pivot){j--;if(j==low) break;}// 3. 两个指针相遇时或跨越后,停止。if(i>=j) break;// 4.交换两个指针的值。int temp=arr[i];arr[i]=arr[j];arr[j]=temp;}// 交换pivot与右指针的值arr[low]=arr[j];arr[j]=pivot;// 分段进行快排quickSort(arr,low,j-1);quickSort(arr,j+1,high);
}
int addedInteger(int* nums1, int nums1Size, int* nums2, int nums2Size) {quickSort(nums1,0,nums1Size-1);quickSort(nums2,0,nums2Size-1);return nums2[0]-nums1[0];
}
  1. 3132. 找出与数组相加的整数 II
void quickSort(int *arr,int low,int high)
{if(high<=low) return;int i=low;int j=high;int pivot=arr[low];while(1){// 1. 自左到右搜索,直到比pivot大后停止。while(arr[i]<=pivot){i++;if(i==high) break;}// 2. 自右到左搜索,直到比pivot小后停止。while(arr[j]>=pivot){j--;if(j==low) break;}// 3. 两个指针相遇时或跨越后,停止。if(i>=j) break;// 4.交换两个指针的值。int temp=arr[i];arr[i]=arr[j];arr[j]=temp;}// 交换pivot与右指针的值arr[low]=arr[j];arr[j]=pivot;// 分段进行快排quickSort(arr,low,j-1);quickSort(arr,j+1,high);
}int minimumAddedInteger(int* nums1, int nums1Size, int* nums2, int nums2Size) {quickSort(nums1,0,nums1Size-1);quickSort(nums2,0,nums2Size-1);for(int i=2;i>=0;i--){int left=i+1,right=1;while(left<nums1Size && right < nums2Size){if(nums1[left]-nums2[right]==nums1[i]-nums2[0])right++;left++;}if(right==nums2Size)return nums2[0]-nums1[i];}return 0;
}
  1. 3148. 矩阵中的最大得分

思路

方法一:动态规划

思路与算法

\(f(i,j)\) 表示以矩阵 \(grid\) 中位置 \((i,j)\) 结束的最大得分。由于每一步只能往右走或者往下走,因此在进行状态转移时,我们分别枚举这两种情况:

对于往右走,我们有:

\[dp(i,j)=\max_{0\leqslant k<j}\{\max\{dp(i,j),0\}+grid(i,j)-grid(i,k)\} \]

这里的 \(\max\{f(i,k),0\}\) 是由于题目要求「必须至少移动一次」,所以 \(f(i,k)\) 中并不包含「以 \((i,k)\) 同时为起点和终点」的情况,需要增加 0 来表示这一情况,才能让状态转移中包含「以 \((i,k)\) 为起点,\((i,j)\) 为终点」的情况。

就算不考虑往右走的情况,上述状态转移方程的时间复杂度也达到了 \(O(mn)×O(n)=O(mn^2)\),会超出时间限制,因此需要进行优化。

注意到 \(grid(i,j)\)\(k\) 无关,我们可以将其从 \(max\) 中提出:

\[dp(i,j)=grid(i,j)+\max_{0\leqslant k<j}\{\max\{dp(i,j),0\}-grid(i,k)\} \]

\(prerow(i,j)=\max\limits_{0\leqslant k<j}\{\max\{dp(i,j),0\}-grid(i,k)\}\),那么可以使用前缀和的思想,在计算完 \(f(i,j)\) 后用 \(O(1)\) 的时间得到它的值:

\[\begin{cases} prerow(i,0)=\max\{dp(i,0),0\}−grid(i,0)\\ prerow(i,j)=\max\{prerow(i,j−1),\max\{dp(i,j),0\}−grid(i,j)\} \end{cases} \]

此时状态转移方程变为简单的递推:

\[dp(i,j)=grid(i,j)+prerow(i,j−1) \]

同理,对于往左走,我们有:

\[dp(i,j)=grid(i,j)+precol(i−1,j) \]

这里 \(precol(i,j)\) 是与 \(prerow(i,j)\) 类似的列的前缀最大值。当所有的 \(dp(i,j)\) 都计算完成后,其中的最大值即为最终的答案。

题解

int maxScore(int** grid, int gridSize, int* gridColSize) {// dp 2-dimensional matrix.int **dp=(int**)malloc(sizeof(int*)*gridSize);int **preRow=(int**)malloc(sizeof(int*)*gridSize);int **preCol=(int**)malloc(sizeof(int*)*gridSize);for(int i=0;i<gridSize;i++){dp[i]=(int*)malloc(sizeof(int)*gridColSize[i]);preRow[i]=(int*)malloc(sizeof(int)*gridColSize[i]);preCol[i]=(int*)malloc(sizeof(int)*gridColSize[i]);for(int j=0;j<gridColSize[i];j++){dp[i][j]=-1e8;preRow[i][j]=0;preCol[i][j]=0;}}int ans=-1e8;for(int i=0;i<gridSize;i++){for(int j=0;j<gridColSize[i];j++){if(i>0)dp[i][j]=dp[i][j]>grid[i][j]+preCol[i-1][j]?dp[i][j]:preCol[i-1][j]+grid[i][j];if(j>0)dp[i][j]=dp[i][j]>grid[i][j]+preRow[i][j-1]?dp[i][j]:grid[i][j]+preRow[i][j-1];ans=ans>dp[i][j]?ans:dp[i][j];preRow[i][j]=preCol[i][j]=(dp[i][j]>0?dp[i][j]:0)-grid[i][j];if(i>0)preCol[i][j]=preCol[i][j]>preCol[i-1][j]?preCol[i][j]:preCol[i-1][j];if(j>0)preRow[i][j]=preRow[i][j]>preRow[i][j-1]?preRow[i][j]:preRow[i][j-1];}}return ans;
}
  1. 2552.统计四元上升数组

class Solution {
public:long long countQuadruplets(vector<int>& nums) {int n=nums.size();vector<int> pre(n+1);long long ans=0,cur=0;for(int j=0;j<n;j++){   cur=0;for(int k=n-1;k>j;k--)  // 从后往前进行枚举{if(nums[j]>nums[k])ans += (long long)(pre[nums[k]])*cur;elsecur++;}for (int x=nums[j]+1;x<=n;x++)pre[x]++;   // 统计从0到j-1的小于x的数}return ans;}
};
  1. 2306. 公司命名

思路(Hash set)

将每一个字符以首字母为key,去掉首字母为后缀存储在hashset中。这样我们就有
a: str1,str2,str3...
b: str1,str2,str3...
然后我们观察是否有重复的后缀。有则去掉。这样就有了
ans+=(a-repeat)*(b-repeat)
作为最终结果。

Code

class Solution {
public:int get_size(unordered_set<string> &a, unordered_set<string> &b){// Count for the intersected suffix.int ans=0;for(const string &s:a){if(b.count(s))ans++;}return ans;}long long distinctNames(vector<string>& ideas) {unordered_map<char, unordered_set<string> > names;  // Hash set put all the names with the same first letter together.for (string &idea:ideas){names[idea[0]].insert(idea.substr(1,idea.size()-1));}long long ans=0;// Check for intersects and count.for(auto [key1,val1]:names){for(auto [key2,val2]:names){if(key1==key2) continue;int intersections=get_size(val1,val2);ans+=static_cast<long long> (val1.size()-intersections)*(val2.size()-intersections);}}return ans;}};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/829104.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20222312 2024-2025-2 《网络与系统攻防技术》实验四报告

一、恶意代码文件类型标识、脱壳与字符串提取对提供的rada恶意代码样本,进行文件类型识别,脱壳与字符串提取,以获得rada恶意代码的编写作者 (1).通过kali中的file命令查看文件格式和可运行平台,即exe文件,Win32平台 通过PEID查壳文件发现使用UPX壳二、使用IDA Pro静态或…

点阵LED电路分析

以点阵的左上角LED为例,即 A1 LED为例,进行电路分析 9号脚接着LED的阳极,所以9号脚需是高电平,13号脚连着LED的阴极,所以13号脚需是低电平 9号脚连接着Q10的集电极,欲使9号脚为高电平,则需要Q10导通 Q10的发射极连接着+5V电压,欲使Q10导通,则基极需为低电平,即LEDC0为…

苹果手机和电脑数据互传

利用共享的文件夹 这个方法简单来说就是iPhone通过远程连接到Windows服务器,利用共享的文件夹来进行照片中转。 注意:iPhone和Windows必须要连接到同一个局域网内! ● Windows设置 第一步,获取Windows电脑的IP地址。 具体操作是先打开“Windows设置-网络和Internet-网络和共…

由一个业务需求引发的对 ASP.NET 全局变量的调研及结果

在单机模式下,使用哪种技术来存储身份状态信息比较安全可靠呢?前言 前段时间使用 ASP.NET MVC + Form Auth 做了一个单机小项目,当时对于采用什么方式来存储登录状态有些纠结,通常的做法是使用 Cookie 或者 Session,但是我想有没有更好的方式来存储登录状态呢?于是花了点…

苹果手机数据传输

利用共享的文件夹 这个方法简单来说就是iPhone通过远程连接到Windows服务器,利用共享的文件夹来进行照片中转。 注意:iPhone和Windows必须要连接到同一个局域网内! ● Windows设置 第一步,获取Windows电脑的IP地址。 具体操作是先打开“Windows设置-网络和Internet-网络和共…

c语言中返回整数值的长度

001、方法1 while循环[root@PC1 test]# ls test.c [root@PC1 test]# cat test.c ## 测试c程序 #include <stdio.h>int get_length(int a) {int length = 0;while(a > 0){length++;a /= 10;}return length; }int main(void) {int a;printf("a = "…

Blender 常用建模操作

常用简单介绍 挤出 快捷键:E 挤出是2个动作,生成加移动,所以右键撤销只能撤销移动内插 快捷键:I 内插仅是一个动作倒角 快捷键:Ctrl+B 滚动滚轮可以增加倒角的段数环切 快捷键:Ctrl+R 滚动滚轮可以增加倒角的段数挤出详细介绍 沿轴线挤出或者自动挤出挤出流形可以向内挤出…

Stack模块的设置

TEAM: Topological Evolution-aware Framework for Traffic Forecasting–Extended Version Motivation 为了捕捉复杂的时空动态,许多基于深度学习的方法最近被提出,并由于其学习非线性动力学[35,59]的能力,在挑战数据集上显示出了有希望的结果。这些方法通常建立在图神经网…

CCPC辽宁省赛赛后总结

2024CCPC辽宁省赛-赛后总结 ​ 写这篇的时候已经是11/8日了,过了半个多星期才开始写,我实在堕落,啊对对对。 ​ 这算是acm生涯中真正意义上的首场了,本来是奔着首银摄金的目标去的,结果拿了个铜尾,导致我们小队闹得不是很愉快,所以来写下这篇总结来避免下次犯错。ps:滚榜…

C++之endl以及它与换行符的区别

看下C++_primer上的一段话,并给予解释:1. endl 是操纵符 在 C++ 中,endl 是一种特殊的操纵符(manipulator),它的作用不仅是结束一行(相当于换行),还会刷新缓冲区。操纵符是一种可以影响输出行为的特殊值,比如 endl、setw 等。 题外话 想要了解更多关于setw的内容,可…

C++之fixed

在 C++ 中,fixed 是一个操纵符(manipulator),用于指定浮点数的显示格式。 在默认情况下,C++ 会使用科学计数法或定点(小数点)格式输出浮点数,具体取决于数值的大小和有效位数。 然而,当使用 fixed 时,它会强制所有浮点数都以定点格式显示,即以小数点后的固定位数输出…