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

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");
    }
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
虚函数表(Virtual Function Table)是一张存储了虚函数地址的表格。每个包含虚函数的类都会有一张对应的虚函数表。该表的每一项都是一个虚函数的地址。这个表是属于类的,而不是属于某个具体的对象,因此一个类只需要一张虚函数表。 虚函数指针(Virtual Function Pointer),也称为vfptr,是指向虚函数表的指针。在一个对象的内存布局中,虚函数指针位于最前端。通过虚函数指针,对象可以在运行时动态地调用正确的虚函数。 具体来说,虚函数指针指向了对象所属类的虚函数表的首地址。通过这个虚函数指针,对象可以访问到自己所属类的虚函数表。而虚函数表中的每一项都是一个虚函数的地址,通过这个地址,对象可以调用对应的虚函数。 总结起来,虚函数表是一张存储了虚函数地址的表格,属于类而不是对象。虚函数指针是指向虚函数表的指针,位于对象的内存布局的最前端。通过虚函数指针,对象可以在运行时动态地调用正确的虚函数。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [虚函数表及虚函数表指针(看似简单,深入部分也不是很懂)](https://blog.csdn.net/fengdijiang/article/details/106737667)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [虚函数指针和虚函数表](https://blog.csdn.net/hrbust_cxl/article/details/117393978)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值