题解 P1286 【两数之和】

提供一个新思路

这题,我们假设n个数分别为a1,a2,a3,a4,a5...an,且对于任意

1<=i<j<=n满足ai<aj

而他们两两之和即为输入的各数字,从中,我们不难推出对于输入的数字中(我们把它们按从小到大排序,分别设为m1,m2...)

一定满足:m1=a1+a2,m2=a1+a3(我们可以用反证法证明结论)

但m3有两种情况:m3=a1+a4或者m3=a2+a3,我们无法判断,那么,

为什么我们不能把a2+a3的情况排除呢?

所以我们可以这样做: 同样枚举a1(1->m1/2),然后算出a2,a3。这时,我们对a2+a3的数字打个标记,当下次访问到的时候将标记取消说明剩下的数字不是a2+a3,那么,剩下的数的最小的那一个一定是a1+a4!同理我们对a2+a4,a3+a4打标记。。。 最后就能求出所有的a了,如果我们求完了n个数,然而,还有数没被打上标记,就说明此时的a1时错误的我们需要重新枚举。

最后,我们就可以求出答案了~

代码:

#pragma GCC optimize(3)//手动Ox优化
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+2;
int a[N],tot;
int biao[N],maxe;
int ans[N];
bool F=0;
int n;
inline void print(){//输出答案
    for(int i=1;i<=n;++i){
        printf("%d ",ans[i]);
    }
    putchar(‘\n‘);
}
inline void dfs(int x){
    memset(biao,0,sizeof(biao));
    ans[1]=x,ans[2]=a[1]-x,ans[3]=a[2]-x;
    biao[ans[2]+ans[3]]++;//标记记得用int,因为可能存在两组数之和相等的情况
    int zhi=4;
    F=1;//假设这次是正确的
    for(int i=3;i<=tot;++i){
        if(biao[a[i]]){
            biao[a[i]]--;
            continue;
        }
        ans[zhi++]=a[i]-x;
        if(zhi>n+1){
            F=0;//本次答案错误
            return;
        }
        for(int j=2;j<zhi-1;++j){
            if(ans[zhi-1]+ans[j]>maxe){//如果和大于最大值,肯定错误,跳过
                F=0;//本次答案错误
                return;
            }
            biao[ans[zhi-1]+ans[j]]++;//打上标记
        }
    }
}
int main(){
    while(~scanf("%d",&n)){
        tot=n*(n-1)/2,maxe=0;
        for(int i=1;i<=tot;++i){
            scanf("%d",&a[i]);
            maxe=maxe>a[i]?maxe:a[i];//求最大值
        }
        sort(a+1,a+tot+1);//排个序~
        bool flag=0;
        for(int i=1;i<=a[1]/2;++i){
            dfs(i);
            if(F){
                flag=1,F=0;//找到正确答案,F记得清零
                print();//输出
                break;
            }
        }
        if(!flag){
            printf("Impossible\n");
            continue;
        }
    }
    return 0;
}
/**
*  ┏┓   ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃       ┃
* ┃   ━   ┃ ++ + + +
*  ████━████+
*  ◥██◤ ◥██◤ +
* ┃   ┻   ┃
* ┃       ┃ + +
* ┗━┓   ┏━┛
*   ┃   ┃ + + + +Code is far away from  
*   ┃   ┃ + bug with the animal protecting
*   ┃    ┗━━━┓ 神兽保佑,代码无bug 
*   ┃        ┣┓
*    ┃        ┏┛
*     ┗┓┓┏━┳┓┏┛ + + + +
*    ┃┫┫ ┃┫┫
*    ┗┻┛ ┗┻┛+ + + +
*/

原文地址:https://www.cnblogs.com/ThinkofBlank/p/10146174.html

时间: 2024-09-30 16:07:35

题解 P1286 【两数之和】的相关文章

[leetcode题解]01两数之和

给定一个整数数组 nums?和一个目标值 target,请你在该数组中找出和为目标值的那?两个?整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组中同样的元素. 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] 分析 关键字:数组.查找.下标. 由于数组是无序的,查找必须要遍历,不能用二分查找,时间复杂度一般最小为O(n). 暴力解法:遍历

LeetCode 题解 | 1. 两数之和

题目描述: 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用. 示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] 方法一.暴力解法: 暴力法很简单,遍历每个元素 ,并查找是否存在一个值与 相等的目标元素. class Solution { public: vector<int> twoSum(vect

LeetCode题解001:两数之和

两数之和 题目 给定一个整数数组 nums?和一个目标值 target,请你在该数组中找出和为目标值的那?两个?整数,并返回他们的数组下标 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组中同样的元素 示例: 给定 nums = [2, 7, 11, 15], target = 9 因为 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] Java: 方法一:暴力法 暴力法很简单,就是用两遍循环的方式遍历nums class Solution {

leetcode T1 两数之和详解

两数之和 题目描述 给定一个整数数组 nums?和一个目标值 target,请你在该数组中找出和为目标值的那?两个?整数,并返回他们的数组下标.你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个数组中同样的元素. 示例 给定 nums = [2, 7, 11, 15], target = 9,因为 nums[0] + nums[1] = 2 + 7 = 9,所以返回 [0, 1] 详细题解 暴力枚举 暴力法的思路很简单:遍历数组nums的每一个元素nums[i],在[i+1, ...,

给定数组A,大小为n,现给定数X,判断A中是否存在两数之和等于X

题目:给定数组A,大小为n,现给定数X,判断A中是否存在两数之和等于X 思路一: 1,先采用归并排序对这个数组排序, 2,然后寻找相邻<k,i>的两数之和sum,找到恰好sum>x的位置,如果sum=x则返回true, 3,找到位置后,保持i不变,从k处向前遍历,直到找到A[k]+A[i]等于x,并返回TRUE,如果找不到,则返回false. 论证步骤3:当前找到的位置恰好A[k]+A[i]>x,且前一位置的sum<x: 所以A[i]前面的数(不包括A[i])无论取哪两个数都

JavaScript-3.1--获取用户的输入,输出用户输入的两数之和---ShinePans

提示用户输入两个数,然后输出用户输入的两数之和 第一次输入 ,输入处为空 第二个输入,输入处为默认27  (这里强调语句的使用) <html> <head> <meta http-equiv="content-type" content="text/html;charset=GB2312"/> <title> 3.1 让用户输入两个数字,然后输出相加的结果 </title> </head> &l

leetcode——Two Sum 两数之和(AC)

Given an array of integers, find two numbers such that they add up to a specific target number. The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that

[LeetCode] Two Sum IV - Input is a BST 两数之和之四 - 输入是二叉搜索树

Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that their sum is equal to the given target. Example 1: Input: 5 / 3 6 / \ 2 4 7 Target = 9 Output: True Example 2: Input: 5 / 3 6 / \ 2 4 7 Targe

编程题:求两数之和

#include<stdio.h>       /*包含输入输出头文件*/ main()                            /*定义主函数*/ {  int a,b,sum;                /*定义整数变量a.b.sum*/ a=123;                        /*给a赋值*/ b=456;                        /*给b赋值*/ sum=a+b;                  /*令sum=a+b*/ p

LeetCode 167. Two Sum II - Input array is sorted (两数之和之二 - 输入的是有序数组)

Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. The function twoSum should return indices of the two numbers such that they add up to the target, where index1 m