B题
现在给定一个数组arr,和a,b两个数字,你要做的就是找到(i,j,k)。且满足
1. 0 <= i < j < k < arr.size()
2. |arr[i] - arr[j]| <= a
3. |arr[j] - arr[k]| <= b
统计满足条件的个数并返回(最后结果可能很大,请取1000000007的余数)。
示例1
输入
[7,1,8,9,0],3,3
返回值
1
说明
只有(7,8,9)符合要求
备注:
arr.size() <= 5000
这个题目朴素做法分别枚举i,j,k会出现一个三重循环,时间复杂度会超过1e9,显然朴素暴力做法时行不通的,我们必须想办法给它进行优化,分析题目所给条件我们可以发现,i,k都可以经过J来划分,以J为第一重循环,然后再分别枚举I,K这样我们的时间复杂度机会降到n方的一个复杂度,大概再2n方左右,是小于1e8的,所以这个做法是可以通过的。
下面给出代码
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param arr int整型vector
* @param a int整型
* @param b int整型
* @return int整型
*/
int countTriplets(vector<int>& arr, int a, int b) {
long long int ans=0,res=0,cns=0;
for(int j=0;j<arr.size();j++)
{ ans=0,res=0;
for(int i=j-1;i>=0;i--)
{
if(abs(arr[i]-arr[j])<=a)ans++;
}
for(int k=j+1;k<arr.size();k++)
{
if(abs(arr[j]-arr[k])<=b)res++;
}
cns=(cns+res*ans)%1000000007;
}
return cns%1000000007;
}
};
C题
链接:https://ac.nowcoder.com/acm/contest/10324/C
来源:牛客网
现在有n个音符和m对共鸣关系,编号为1~n,每个音符自己有一个奏响时的优美程度,共鸣关系(x,y,z)表示音符x和y同时奏响的额外优美程度是z,同时不奏响则为-z,其他情况为0。
音符可以选择奏响或者不奏响,不奏响的音符没有优美程度。我们想知道最大的优美程度和是多少,我们不需要知道具体是哪些音符被奏响了,只需输出最大和即可。
共鸣关系可能有重复,其共鸣效果也会重复叠加。
示例1
输入
2,1,[-10,-10],[[1,2,5]]
返回值
-5
备注:
数据包括两个数n,m,一个长度为n的数组a[],表示每个音符奏响时的优美程度(a[0]表示第一个音符),一个第一维长度为m的二维数组,描述m组共鸣关系。
输出一个整数表示答案。
n,m<=100000,所有的优美程度和额外优美程度的绝对值<=33000
这个题目时非常考察思维的,分析题目,我们可以发现每一个组合若X与Y同时开启,则收益为Z,若同时不开启则为-Z,那么其他情况X !Y ,!X Y的收益时0,那么我们可以把初始收益设置为-Z,开启X增加Z,开启Y也增加Z。那么每一个音符是否奏响那就看它本来奏响的收益加上额外收益是否大于零,若大于零则奏响。
下面来看代码
链接
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param n int整型
* @param m int整型
* @param a int整型vector
* @param b int整型vector<vector<>>
* @return long长整型
*/
long long wwork(int n, int m, vector<int>& a, vector<vector<int> >& b) {
vector<long long int> p(n);
long long int res=0;
for(auto item : b)
{ res-=item[2];
p[item[0]-1]+=item[2];
p[item[1]-1]+=item[2];
}
for(int i=0;i<n;i++)
{
if(a[i]+p[i]>0)res+=a[i]+p[i];
}
return res;
}
};