Hrbust 1734 a + b + c=0【双指针】

本文解析了一道经典的算法题——寻找数组中三个数相加等于零的所有组合,并给出了解题思路及AC代码实现。

a + b + c=0

Time Limit: 1000 MS

Memory Limit: 65535 K

 

Total Submit: 85(23 users)

Total Accepted: 21(17 users)

Rating: 

Special Judge: No

 

Description

There is a sequence A containing n integers.

How many combinations can make a + b + c = 0 (a∈A, b∈A, c∈A).

Input

There are multiple test cases. The first line is an positive integer T standing for the number of test cases.

For each test case, the first line is one integer n.

The second line are n integers a1, a2, ..., an, separated by space.

(1<=n<=5000,|ai|<=100 000 000)

Output

For each test case, output all the combination satisfied a + b + c=0, by lexicographical order.

If there doesn't exit, output "<empty>" in one line.

Output a blank line after each test case.

Sample Input

2

6

-1 0 1 2 -1 -4

6

1513 5031 5031 -1582 4769 10

Sample Output

-1 -1 2

-1 0 1

 

<empty>

Source

哈理工2013春季校赛 - 现场赛(热身)


题目大意:


输出字典序升序条件下的没有重复的所有三元组(a,b,c),使得a+b+c==0


思路:(一个煞笔的思路构建过程........)


1、首先,字典序升序输出同时也提醒了我们排序来做,其实即使开了spj没有提醒排序,我们也能很容易想到排序吧...............那么,排序是首要步骤


2、看到N是5000.首先我们最无脑的方式就是N^3枚举,显然会超时,最简单的也是最好想的就是N^2LogN,先对序列排序,之后N^2枚举a,b,然后因为序列是递增的,所以a+b+编号为mid的数是递增的,所以可以二分查找,时间复杂度O(N^2LogN)如果N==1000其实还是有点希望过掉的,然而N==5000,还是光荣的TLE了


3、然后想办法将N^2LogN再降掉一些就差不多了,然后想到N^2枚举a,b,用Hash表查-(a+b),能够达到N^2的时间复杂度,只可惜,题目不保证数据不重复,反而样例都已经告诉你会有重复的数据出现了,去重去了半天,最后还是投降了。


4、最后能想到的办法就是双指针了,一层for枚举a,然后定义两个指针ii,jj,因为序列是递增的,所以:

①如果a+num【ii】+num【jj】>0 jj--;

②如果a+num【ii】+num【jj】<0 ii++;

③如果a+num【ii】+num【jj】==0;jj--,并处理相同解(去重解)。ii++,


T T 为什么我没有直接向用指针法来做....................


Ac代码:


#include<stdio.h>//N^2LogN TLE
#include<algorithm>
#include<string.h>
using namespace std;
int a[5005];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        int flag=0;
        sort(a,a+n);
        for(int i=0;i<n;i++)
        {
            if(i!=0&&a[i]==a[i-1])continue;
            int ii=i+1;
            int jj=n-1;
            while(ii<=jj&&ii<n&&jj>i+1)
            {
                int tmp=a[ii]+a[jj]+a[i];
                if(tmp>0)
                {
                    jj--;
                }
                else if(tmp<0)
                {
                    ii++;
                }
                else
                {
                    if(ii!=i&&ii!=jj&&ii!=jj)
                    {
                        flag=1;
                        printf("%d %d %d\n",a[i],a[ii],a[jj]);
                    }
                    jj--;
                    while(a[ii]==a[ii+1]&&ii<n)ii++;
                    ii++;
                }
            }
        }
        if(flag==0)
        {
            printf("<empty>\n");
        }
        printf("\n");
    }
}




基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究(Matlab代码实现)内容概要:本文围绕“基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究”,介绍了利用Matlab代码实现配电网可靠性的仿真分析方法。重点采用序贯蒙特卡洛模拟法对配电网进行长时间段的状态抽样与统计,通过模拟系统元件的故障与修复过程,评估配电网的关键可靠性指标,如系统停电频率、停电持续时间、负荷点可靠性等。该方法能够有效处理复杂网络结构与设备时序特性,提升评估精度,适用于含分布式电源、电动汽车等新型负荷接入的现代配电网。文中提供了完整的Matlab实现代码与案例分析,便于复现和扩展应用。; 适合人群:具备电力系统基础知识和Matlab编程能力的高校研究生、科研人员及电力行业技术人员,尤其适合从事配电网规划、运行与可靠性分析相关工作的人员; 使用场景及目标:①掌握序贯蒙特卡洛模拟法在电力系统可靠性评估中的基本原理与实现流程;②学习如何通过Matlab构建配电网仿真模型并进行状态转移模拟;③应用于含新能源接入的复杂配电网可靠性定量评估与优化设计; 阅读建议:建议结合文中提供的Matlab代码逐段调试运行,理解状态抽样、故障判断、修复逻辑及指标统计的具体实现方式,同时可扩展至不同网络结构或加入更多不确定性因素进行深化研究。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值