2. Two Sum II – Input array is sorted

本文介绍了解决已排序数组中寻找两个数使它们的和等于特定目标值的问题的两种方法。第一种方法通过双指针技巧从前向后遍历数组来找到匹配的元素;第二种方法利用二分查找提高搜索效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Question:
Similar to Question [1. Two Sum], except that the input array is already sorted in
ascending order.

solution1
使用两个下标,一个i=0,一个j=nums.size();从后往前计算

//做出来还是挺开心的,问题代码可太复杂了,答案是简化了一波,感觉很优秀了
vector<int> twoSum(vector<int>& nums, int target)
{
	unordered_map<int, int> map;
	vector<int> ret;
	int j = nums.size()-1;
	int len = nums.size()%2;
	if (len == 1)
		len = nums.size() / 2 + 1;
	else
		len = nums.size() / 2;
	for (int i = 0; i < len; i++)
	{
		while (nums[i] + nums[j] > target)
		{
			j--;
		}
		if (nums[i] + nums[j] == target)
		{
			//cout << i << " " << j << endl;
			ret.push_back(i);
			ret.push_back(j);
		}
	}
	return ret;
}
//answer
vector<int> twoSum(vector<int>& nums, int target)
{
	vector<int> ret;
	int j = nums.size() - 1;
	int i = 0;
	while (i < j)
	{
		if (nums[i] + nums[j] == target)
		{
			//cout << i << " " << j << endl;
			ret.push_back(i);
			ret.push_back(j);
			i++; 
		}
		else if (nums[i] + nums[j] > target)
			j--;
		else
			i++;
	}
	return ret;
}

solution 2
对于有序的数组,查找效率想要高一点,考虑二分查找。

// test1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include "pch.h"
#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>
using namespace std;

int search(vector<int> nums, int i, int target);

vector<int> twoSum(vector<int>& nums, int target)
{
	vector<int> ret;
	for (int i = 0; i < nums.size() / 2; i++)
	{
		int tar = target - nums[i];
		if (search(nums, i,tar) != -1&&search(nums,i,tar)>i)
		{
			cout << i << " " << tar << endl;
			ret.push_back(i);
			ret.push_back(search(nums, i,tar));
		}
	}
	return ret;
}

int search(vector<int> nums, int i,int target)
{
	int len = nums.size()-1;
	while (i<len)
	{
		int mid = (len + i) / 2;
		if (nums[mid] > target)
			len = mid;
		else
			i = mid;
	}	
	return (len = i && nums[len] == target) ? len : -1;
}

int main()
{
	vector<int> nums = {2,3,3,4,5};
	twoSum(nums, 7);
	return 0;
}

又是开心的一天呢。

   There is an empty matrix M of size n×m . Zhongkao examination is over, and Daniel would like to do some puzzle games. He is going to fill in the matrix M using permutations of length m . That is, each row of M must be a permutation of length m† . Define the value of the i -th column in M as vi=MEX(M1,i,M2,i,…,Mn,i)‡ . Since Daniel likes diversity, the beauty of M is s=MEX(v1,v2,⋯,vm) . You have to help Daniel fill in the matrix M and maximize its beauty. † A permutation of length m is an array consisting of m distinct integers from 0 to m−1 in arbitrary order. For example, [1,2,0,4,3] is a permutation, but [0,1,1] is not a permutation (1 appears twice in the array), and [0,1,3] is also not a permutation (m−1=2 but there is 3 in the array). ‡ The MEX of an array is the smallest non-negative integer that does not belong to the array. For example, MEX(2,2,1)=0 because 0 does not belong to the array, and MEX(0,3,1,2)=4 because 0 , 1 , 2 and 3 appear in the array, but 4 does not. DeepL 翻译    有一个大小为 n×m 的空矩阵 M 。 中考结束了,丹尼尔想做一些益智游戏。他打算用长度为 m 的排列填充矩阵 M 。也就是说, M 的每一行都必须是长度为 m† 的排列。 将 M 中 i /th列的值定义为 vi=MEX(M1,i,M2,i,…,Mn,i)‡ 。因为丹尼尔喜欢多样性,所以 M 的美是 s=MEX(v1,v2,⋯,vm) 。 你必须帮助丹尼尔填入矩阵 M ,并最大化它的美感。 † 长度为 m 的排列是由 m 个不同的整数组成的数组,这些整数从 0 到 m−1 按任意顺序排列。例如, [1,2,0,4,3] 是一个排列,但 [0,1,1] 不是一个排列( 1 在数组中出现了两次), [0,1,3] 也不是一个排列( m−1=2 ,但数组中有 3 )。 ‡ 数组的 MEX 是不属于数组的最小非负整数。例如, MEX(2,2,1)=0 是因为 0 不属于数组,而 MEX(0,3,1,2)=4 是因为 0 、 1 、 2 和 3 出现在数组中,但 4 不属于数组。    Input The first line of input contains a single integer t (1≤t≤1000 ) — the number of test cases. The description of test cases follows. The only line of each test case contains two integers n and m (1≤n,m≤2⋅105 ) — the size of the matrix. It is guaranteed that the sum of n⋅m over all test cases does not exceed 2⋅105 . DeepL 翻译    输入 输入的第一行包含一个整数 t ( 1≤t≤1000 ) - 测试用例的数量。测试用例说明如下。 每个测试用例的唯一一行包含两个整数 n 和 m ( 1≤n,m≤2⋅105 ) - 矩阵的大小。 保证所有测试用例
最新发布
03-21
<think>好的,我现在需要解决用户的问题:如何根据给定的n和m构造矩阵M来最大化其美丽值s,其中涉及到排列组合以及MEX运算的具体实现方法。首先,我需要明确几个关键概念,比如美丽值s的定义,MEX运算的含义,以及矩阵构造的具体条件。用户提到“构造矩阵以最大化其美的值”,但具体如何计算可能需要进一步分析。 根据问题描述,美丽值s可能与矩阵中每行的MEX值有关。MEX(Minimum Excluded Value)指的是在一个集合中未出现的最小非负整数。例如,集合{0,1,2}的MEX是3,而{1,2,3}的MEX是0。因此,每行的MEX值计算后,可能需要将这些值求和得到s。目标就是构造一个n行m列的矩阵,使得s最大化。 接下来,我需要考虑矩阵构造的策略。假设每行的MEX尽可能大,那么每行需要包含尽可能多的连续非负整数从0开始。例如,如果一行有m个元素,那么如果这行包含0到m-1的所有数,MEX就是m,这可能是最大的可能值。但可能受限于矩阵元素的范围和排列方式,因为矩阵中的元素需要满足某些条件,比如可能的重复或其他限制? 用户没有给出具体的限制条件,可能需要假设矩阵中的元素可以是任意整数,或者需要满足每行是某种排列。例如,可能每行必须是一个排列,或者元素范围在某个区间内。如果假设每行可以包含重复元素,但需要构造矩阵使得每行的MEX最大化,那么可能的策略是让每行尽可能包含0到k的连续数,使得MEX为k+1。 但需要考虑m的列数。例如,若m=3,那么如果每行包含0,1,2,那么MEX是3。如果列数更多,比如m=5,那么如果能包含0,1,2,3,4,则MEX为5。所以每行的MEX最大值是m,当该行包含0到m-1的所有数时。因此,如果每行都满足这个条件,那么总s为n*m。但是这可能要求矩阵中的元素在每行都恰好包含0到m-1的每个数至少一次,但这可能需要每行是排列,也就是每行是0到m-1的排列,且没有重复元素。如果允许重复,那么可能存在其他情况,但MEX可能不会更高。例如,如果一行是0,0,0,那么MEX是1,但如果一行是0,1,2,则MEX是3。因此,为了最大化每行的MEX,每行必须包含0到m-1的所有数,即每行是0到m-1的一个排列。 因此,构造的矩阵M应该是一个n行m列的矩阵,每行都是0到m-1的一个排列,这样每行的MEX为m,总s=n*m。这样就能最大化s的值。但需要验证这个结论是否正确,是否存在其他情况使得s更大。 例如,假设m=3,n=2。如果每行都是0,1,2的排列,那么每行的MEX是3,总和是6。如果有某行包含0,0,2,那么该行的MEX是1,总和可能更低。但如果允许更大的数值?比如,如果某行包含0,1,3,那么MEX是2,这反而更小。因此,要让MEX最大化,每行必须包含所有0到m-1的数值,且不缺少任何数。因此,每行必须是0到m-1的排列,这样MEX为m,这是每行的最大值。 因此,构造这样的矩阵的方法是让每行都是0到m-1的一个排列,这样总美丽值s=n*m。这应该是最大的可能值。 接下来需要考虑具体如何构造这样的矩阵。例如,在MATLAB中,可以使用perms函数生成排列,但要注意当m较大时,排列的数量会非常大,而n可能小于m!,因此可能需要重复某些排列。但题目没有限制每行的排列必须不同,因此可以重复使用相同的排列。例如,如果n=5,m=3,那么可以每行都是0,1,2的排列,或者任何其排列,只要每行包含0到m-1的所有数即可。 但需要注意,矩阵中的元素可能需要是唯一的排列,或者允许重复?题目中并没有说明,因此可能允许重复。因此,构造这样的矩阵时,每行只要是一个排列即可,不论其他行是否重复。 因此,构造方法即为每行都包含0到m-1的所有数,即每行是一个排列。此时,美丽值总和为n*m,这是最大的可能值。 但需要确认是否存在其他可能的构造方式使得s更大。例如,如果某个行的MEX超过m,这显然不可能,因为MEX定义为未出现的最小非负整数。如果某行包含所有0到m-1的数,则MEX为m,而如果该行包含更大的数,比如0,1,2,...,m-1, m,那么MEX依然是m,因为0到m-1都出现了,所以MEX是m。但是这样的行可能包含m+1元素,但题目中的矩阵是m列,所以每行只能有m个元素。如果其中包含0到m-1,那么不管是否有更大的数值,MEX都是m。例如,一行是0,1,3,其中m=3,则该行的MEX是2,而如果该行是0,1,2,3,但列数m=4,那么MEX是4。所以关键是要在每行中包含0到k的所有数,其中k尽可能大,直到m-1。 因此,结论是,当每行恰好是0到m-1的一个排列时,每行的MEX是m,总和为n*m,这是最大可能值。因此,构造矩阵的方法就是每行都是0到m-1的一个排列。如果允许重复排列,那么直接每行使用相同的排列即可。例如,在MATLAB中,可以先生成一个排列,然后重复n次。或者随机生成不同的排列,只要每行包含所有0到m-1的元素。 现在需要考虑具体如何实现。例如,在MATLAB中,如何生成这样的矩阵。例如,可以使用perms函数生成所有排列,然后选择前n行。但perms当m较大时会有问题,因为排列数太多。或者,使用randperm(m)来生成每行的排列。例如,对于每行i,生成一个随机排列,如M(i,:) = randperm(m)-1(因为MATLAB的randperm生成的是1-based,所以需要减1得到0-based)。 例如,构造n=3,m=4的矩阵: 行1:2 3 0 1 行2:1 0 3 2 行3:0 1 2 3 每行的MEX都是4,总和s=3*4=12。 因此,这样的构造方式是正确的。 接下来,用户的问题可能涉及到如何在编程中实现这一点,比如在MATLAB中如何生成这样的矩阵。例如,使用循环生成每行的排列: M = zeros(n, m); for i = 1:n M(i,:) = randperm(m) - 1; end 这样得到的矩阵每行都是0到m-1的排列,从而每行的MEX为m,总和s=n*m。 但需要验证是否存在其他构造方式使得s更大。例如,如果允许某些行的元素超过m-1,但根据MEX的定义,如果某行包含0到m-1的数,无论是否还有其他更大的数,MEX都是m。例如,某行是[0,1,2,5],当m=4时,该行的MEX是3,因为0,1,2存在,缺少3。所以如果某行包含0到m-1的所有数,则无论是否有更大的数,MEX都是m。因此,如果在构造矩阵时,某些行包含更大的数,但依然包含0到m-1,则不影响MEX的值。例如,当m=3,某行是[0,1,2,4](但列数m=3,这不可能),所以每行必须有m个元素。因此,在列数m的情况下,每行必须恰好有m个元素,若想要MEX为m,必须包含0到m-1的所有数,因为如果有任何一个数在0到m-1之间缺失,那么MEX将是该缺失的数,从而小于m。 因此,结论是,每行必须包含0到m-1的所有数,即每行是一个排列,才能保证该行的MEX为m,从而总和s最大化为n*m。 所以,构造方法即为生成一个n行m列的矩阵,其中每行是0到m-1的一个排列。在MATLAB中,可以通过循环生成每行的排列,或者使用其他方法。 此外,用户提到的MEX计算可能需要在代码中实现。例如,计算每行的MEX的函数。在MATLAB中,可以编写一个函数来计算给定向量的MEX值。例如: function mex_val = compute_mex(vec) sorted_vec = sort(vec); mex_val = 0; for i = 1:length(sorted_vec) if sorted_vec(i) > mex_val break; elseif sorted_vec(i) == mex_val mex_val = mex_val + 1; end end end 然后,对矩阵的每一行应用此函数,计算所有行的MEX值之和。 总结,构造矩阵的方法是将每行设为0到m-1的排列,从而最大化每行的MEX,总和为n*m。这是问题的最优解。</think>### 矩阵构造方法及美丽值最大化分析 要构造一个$n$行$m$列的矩阵$M$,使其美丽值$s$(各行的MEX值之和)最大化,需遵循以下步骤: #### 1. MEX运算定义 MEX(Minimum Excluded Value)是集合中未出现的最小非负整数。例如: - 集合$\{0,1,2\}$的MEX为$3$; - 集合$\{1,2,3\}$的MEX为$0$。 #### 2. 最大化美丽值的策略 每行的MEX值最大化条件是**包含所有非负整数$0$到$m-1$**。此时该行的MEX值为$m$,是理论最大值。若矩阵每行均满足此条件,则总美丽值为: $$s = n \times m$$ #### 3. 矩阵构造方法 - **每行必须为$0$到$m-1$的排列**:确保所有元素$0$到$m-1$存在且不重复。 - **实现示例(MATLAB)**: ```matlab M = zeros(n, m); for i = 1:n M(i, :) = randperm(m) - 1; % 生成0到m-1的随机排列 end ``` #### 4. MEX值计算验证 通过自定义函数验证每行的MEX值: ```matlab function mex_val = compute_mex(vec) sorted_vec = sort(vec); mex_val = 0; for i = 1:length(sorted_vec) if sorted_vec(i) > mex_val break; elseif sorted_vec(i) == mex_val mex_val = mex_val + 1; end end end ``` 对矩阵逐行调用此函数并求和,可验证$s = n \times m$。 #### 5. 理论依据 - 若某行缺少$k \in [0, m-1]$,则其MEX值为$k < m$,导致总美丽值降低。 - 重复或添加更大数值不影响MEX值,但需确保$0$到$m-1$完整覆盖[^2][^3]。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值