[Daimayuan]数组操作(C++,字符串)
Posted WitheredSakura_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Daimayuan]数组操作(C++,字符串)相关的知识,希望对你有一定的参考价值。
给你一个有 n n n 个元素的数组 a a a 。你可以对它进行如下操作,次数不限。
从一个偶数大小为 2 k 2k 2k 的数组中选择一些从位置 l l l 开始的子数组( 1 ≤ l ≤ l + 2 ∗ k − 1 ≤ n 1≤l≤l+2*k−1≤n 1≤l≤l+2∗k−1≤n , k ≥ 1 k≥1 k≥1) ,对于 0 0 0 到 k − 1 k−1 k−1(包括)之间的每一个 i i i ,将值 a l + k + i a_l+k+i al+k+i 分配给 a l + i a_l+i al+i 。
例如,如果 a = [ 2 , 1 , 3 , 4 , 5 , 3 ] a=[2,1,3,4,5,3] a=[2,1,3,4,5,3] ,然后选择 l = 1 l=1 l=1 和 k = 2 k=2 k=2 ,应用这个操作,数组将变成 a = [ 3 , 4 , 3 , 4 , 5 , 3 ] a=[3,4,3,4,5,3] a=[3,4,3,4,5,3]。
请找出使数组中所有元素相等所需的最少操作数(可能是零)。
输入格式
输入由多个测试用例组成。第一行输入一个整数 t t t( 1 ≤ t ≤ 2 × 1 0 4 1≤t≤2×10^4 1≤t≤2×104)表示测试用例的数量。
每个测试用例的包含 ( n + 1 ) (n+1) (n+1) 个整数:
第一个整数 n n n( 1 ≤ n ≤ 2 × 1 0 5 1≤n≤2×10^5 1≤n≤2×105) 表示数组的长度。
此后 n n n 个整数 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an( 1 ≤ a i ≤ n 1≤a_i≤n 1≤ai≤n) 表示数组的元素。
输出格式
输出 t t t 行,每行一个整数表示用给定的操作使数组中所有元素相等所需的最小操作数。
样例输入
5
3 1 1 1
2 2 1
5 4 4 4 2 4
4 4 2 1 3
1 1
样例输出
0
1
1
2
0
数据规模
保证所有测试用例的 n n n 之和不超过 200000 200000 200000。
提示
在第一个测试中,所有元素都是相等的,因此不需要任何操作。
在第二个测试中,你可以应用一个操作, k = 1 k=1 k=1, l = 1 l=1 l=1,设置 a 1 ← a 2 a_1←a_2 a1←a2 ,通过 1 1 1 个操作,数组变成 [ 1 , 1 ] [1,1] [1,1]。
在第三个测试中,你可以应用一个操作, k = 1 k=1 k=1, l = 4 l=4 l=4,设置 a 4 ← a 5 a_4←a_5 a4←a5 ,然后数组变成 [ 4 , 4 , 4 , 4 , 4 ] [4,4,4,4,4] [4,4,4,4,4]。
在第四个测试中,你可以应用一个操作, k = 1 k=1 k=1, l = 3 l=3 l=3,设置 a 3 ← a 4 a_3←a_4 a3←a4 ,数组变成 [ 4 , 2 , 3 , 3 ] [4,2,3,3] [4,2,3,3],然后你可以应用另一个操作, k = 2 k=2 k=2, l = 1 l=1 l=1,设置 a 1 ← a 3 a_1←a_3 a1←a3, a 2 ← a 4 a_2←a_4 a2←a4, 数组变成 [ 3 , 3 , 3 , 3 ] [3,3,3,3] [3,3,3,3]。
在第五次测试中,只有一个元素,因此不需要任何操作。
解题思路
首先解释一下有点难懂的题意
简单来说就是 a 1 , a 2 , . . . , a k a_1,a_2,...,a_k a1,a2,...,ak <- a k + 1 , a k + 2 , . . . a 2 k a_k+1,a_k+2,...a_2k ak+1,ak+2,...a2k(要求一一对应)
举个例子,一个长度为 2 n 2n 2n的数组,我们可以用后 n n n个元素赋值给前 n n n个元素
但是所有的操作数是连续的,也就是说,对于一个长度为 2 n + 1 2n+1 2n+1的数组,你不能用后 n n n个元素赋值给前 n n n个元素,因为中间有一个间隔元素
接下来讲解解题思路
根据题意,我们只能把后面的数赋值给前面,而不能反过来,所以最后所有数一定都会变为最后一个数
那么我们从后方开始操作数组,累计当前已经成功匹配的长度
当我们尝试匹配下一个元素的时候,有两种情况:
(1)匹配成功,不需要操作:将当前匹配长度
+
1
+1
+1,continue
(2)匹配失败,需要操作:将之前已经匹配的所有元素向前赋值
不断循环,直到所有元素都匹配成功
最后,AC代码如下
#include <iostream>
using namespace std;
const int max_n = 2e5;
int t, n, num_arr[max_n];
int main()
cin >> t;
for (int i = 0; i < t; i++)
cin >> n;
for (int i = 0; i < n; i++)
cin >> num_arr[i];
int match = num_arr[n - 1];
int len = 0, ans = 0;
for (int i = n - 1; i >= 0; i--)
if (num_arr[i] == match) len++;
else
i -= len - 1;
len *= 2;
ans++;
cout << ans << endl;
return 0;
[Daimayuan]新国王游戏(C++,数学)
又到了 H H H 国国庆, 国王再次邀请 n n n 位大臣来玩有奖游戏。上次国庆被众臣吐槽国王小气后,国王决定今年大方点,改变游戏规则且不再参与游戏,免得被大臣们质疑。首先, 他让每位大臣在左、 右手上面分别写下一个正整数。然后让这 n n n 位大臣排成一排。排好队后, 所有的大臣都会获得国王奖赏的若千金币, 每位大臣获得的金币数分别是:排在该大臣后面的所有人的左手上的数的乘积乘以他自己右手上的数。国王希望所有大臣获得的金币数之和最多,所以他想请你帮他重新安排一下队伍的顺序。
简而言之,给定 n n n 对数 a i , b i a_i,b_i ai,bi,找到一种排列顺序,使得 b 1 × a 2 ∗ a 3 ∗ … a n + b 2 × a 3 ∗ a 4 ∗ … a n + ⋯ + b n b_1×a_2∗a_3∗…a_n+b_2×a_3∗a_4∗…a_n+⋯+b_n b1×a2∗a3∗…an+b2×a3∗a4∗…an+⋯+bn 最大,求最大值,由于答案可能很大,需要对 1000000007 1000000007 1000000007 取模
输入格式:
第一行,包含一个整数 n n n。 第二行到第 n + 1 n+1 n+1 行,包含两个整数 a i , b i a_i,b_i ai,bi
输出格式:
输出一行,表示按某种排序后的 b 1 × a 2 ∗ a 3 ∗ … a n + b 2 × a 3 ∗ a 4 ∗ … a n + ⋯ + b n b_1×a_2∗a_3∗…a_n+b_2×a_3∗a_4∗…a_n+⋯+b_n b1×a2∗a3∗…an+b2×a3∗a4∗…an+⋯+bn 的最大值对 1000000007 1000000007 1000000007 取模的结果
样例输入
2
1 2
3 4
样例输出
10
说明
只有两种情况:
1. 1. 1.
1 2
3 4
( 2 ∗ 3 ) + 4 = 10 (2∗3)+4=10 (2∗3)+4=10
2. 2. 2.
3 4
1 2
( 4 ∗ 1 ) + 2 = 6 ( 4 ∗ 1 ) + 2 = 6 (4∗1)+2=6(4∗1)+2=6 (4∗1)+2=6(4∗1)+2=6
所以答案为 10 10 10
数据限制
对于 100 100 100% 的数据,保证 1 ≤ n ≤ 1 0 6 1≤n≤10^6 1≤n≤106, 1 ≤ a i , b i ≤ 2 30 1≤a_i,b_i≤2^30 1≤ai,bi≤230
解题思路
思路很简单:先排序,然后累加求和
解题关键在于如何排序
采用算法sort()
进行排序,我们需要做的就是重载比较运算符,而重载比较运算符,我们就只需要考虑一种简单的比较情形:相邻对换
对于 i , i + 1 i,i+1 i,i+1两位大臣,我们不需要考虑其 i i i前面的人和 i + 1 i+1 i+1后面的人,因为他们的顺序是不变的
我们只需要考虑两位大臣调换前后二者获取的金币变多了还是变少了
在调换之前: b i ∗ a i + 1 + b i + 1 b_i*a_i+1+b_i+1 bi∗ai+1+bi+1
在调换之后: b i + 1 ∗ a i + b i b_i+1*a_i+b_i bi+1∗ai+bi
比较二者的大小即可知道哪种排序获得的金币更多
AC代码如下
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int max_n = 1e6;
const int max_ab = pow(2, 30);
const int mod_num = 1000000007;
struct person long long l, r; persons[max_n + 1];
int main()
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> persons[i].l >> persons[i].r;
sort(persons + 1, persons + 1 + n, [](person p1, person p2)
return p1.r * p2.l + p2.r > p2.r * p1.l + p1.r;
);
long long ans = 0;
long long sum = 1;
for (int i = n; i > 0; i--)
ans = (ans + persons[i].r * sum) % mod_num;
sum = (sum * persons[i].l) % mod_num;
cout << ans << endl;
return 0;
以上是关于[Daimayuan]数组操作(C++,字符串)的主要内容,如果未能解决你的问题,请参考以下文章
字符串数组 C# 与 C++ dll 的互操作性;从 C# 到 C++ dll 的字符串数组,它设置数据并将其发送回 c#