可达#P1064. 和为指定数

 

问题描述

输入 n(n≤1000,000) 个整数,找出其中的两个数,他们之和等于整数 m (假定肯定有解)。所有数都能用int表示

输入格式

第一行: 一个整数 n 表示有多少个数;

第二行: n 个整数,用空格隔开;

第三行: 一个整数 m。

输出格式

从小到大,输出所有的组合方案。

一行输出一组方案,用空格隔开;

样例

输入数据 1

9
21 4 5 6 13 65 32 9 23
28

Copy

输出数据 1

5 23

1:方法解析

L3/L4 尺取法

尺取法

科普一下,尺取法有两种形式,分别为反向扫描反向扫描和同向扫描同向扫描, 

 !相对着扫描,叫做反向扫描;核心代码为:

// 尺取法-反向扫描
while(i < j){     
	// if(.....)  
	i++;          
	// if(.....)  
	j--;          
}

再看这两个人,他们沿同一方向运动,所以是同向扫描,核心代码:

// 尺取法-同向扫描 
int i2 = 1, j2 = 1;
while(j < n){      
	// if(......)  
	i2++;          
	// if(.....)   
	j2++;          
}

代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, a[N], c;
int main(){
    cin >> n;
    for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
    cin >> c;
    sort(a+1,a+n+1);// 1.进行排序     
    int l = 1, r = n;// 反向寻找,一个头,一个尾
    while(l < r){// 只要头尾不重合
        int sum = a[l] + a[r];
        if(sum == c) {
            cout << a[l] << " " << a[r] << endl;
            l++;
        }else if(sum > c) {
            r--;// 如果结果大了,右边调小一点
        }else if(sum < c){
            l++;// 如果结果小了,左边大一些
        }
    }
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值