首页 > 其他分享 >Sumsets(UVA10125)整数集合

Sumsets(UVA10125)整数集合

时间:2023-11-25 15:24:41浏览次数:36  
标签:p1 key int UVA10125 整数 && ans data Sumsets

备课的时候发现了这道题,对于初识哈希来说并不算一道很简单的题。在查阅林厚从老师的示例代码与往届OI选手的博客后,大致理解了本题的思路。

相关标签: Hash

跳转至本题

Description

给定一个整数集合S,求一个最大的d,满足a+b+c=d,其中a,b,c,d∈S

Input

多组数据,每组数据包括:

  • 第一行一个整数n,代表元素个数
  • 下面n行每行一个整数,代表集合元素

输入结束的标志为n=0。

Output

对于每组数据,输出:

  • 一行,如果有解,输出一个整数,代表最大的d;否则输出no solution

Sample Input

5
2
3
5
7
12
5
2
16
64
256
1024
0
 

Sample Output

12
no solution
 

Hint

n≤1000,保证输入的集合元素互不相同。

集合中的元素∈[-536 870 912,536 870 911]。

 

解题思路

a,b,c,d。共四个数,如果想采用最简单枚举法,复杂度将来到O(n4)。题目数据来说,一定会超时。

考虑题目数据量约在103,O(n2)的做法差不多能够接受。考虑做以下方法:找到两组对,使得  d-c = a+b 。若等式满足,更新d的最大值即可。

如何快速找到、定位两组值?考虑使用Hash方法。即先用n2的时间(两重循环)枚举a+b,并将其打包成对,以a+b的值为key,存入Hash数组中。

再用n2的时间(两重循环)枚举d-c,并将b-c的值作为键,在Hash数组中查找是否存在。如果能找到key相同的node点,则找到了一组满足 d-c = a+b的值。(注意检查a b c d 四个数不重复)

此时,维护ans更新为更大的d值即可。如果找不到此组合,则输出no solution

通过代码

#include<iostream>
#include<cstdio>
#include<cstring>
#define inf -536870912
using namespace std;

const int maxM=1000007;
const int maxN=1010;

int n;
int hash1[3*maxM], a[maxN]; //hash table  --  source data
struct node{
    int key,x1,x2,next;
}data[maxN * maxN]; //hash node

int main(){
    while(scanf("%d",&n) && n){
        for(int i=1;i<=n;i++) scanf("%d",a+i);
        memset(hash1,0,sizeof(hash1));
        memset(data,0,sizeof(data));
        int k=0;
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                data[++k].key=a[i]+a[j]; data[k].x1=i; data[k].x2=j;
                int x=data[k].key % maxM;
                if(x<0) x=-x;
                while(hash1[x]>0) {
                    x=x+1;
                    x=x % maxM;
                }
                hash1[x]=k;
            }
        }
        int ans=inf;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++) if(j!=i){
                int key=a[i]-a[j];
                int x=key % maxM;
                if(x<0) x=-x;
                int p=x;
                int flag=0;
                while(hash1[p]>0 && !flag){
                    int p1=hash1[p];
                    if (data[p1].key==key && data[p1].x1!=i && data[p1].x2!=i && data[p1].x1!=j && data[p1].x2!=j) flag=1;
                    else {
                        p=p+1; p = p%maxM;
                    };
                } 
                if(hash1[p]>0 && a[i]>ans) ans=a[i]; 
            }
        }
        if(ans!=inf) cout<<ans<<endl;
        else cout<<"No Solution"<<endl;
    }
}

 

标签:p1,key,int,UVA10125,整数,&&,ans,data,Sumsets
From: https://www.cnblogs.com/Uninstalllingyi/p/17855551.html

相关文章

  • 001反转一个3位整数
    1.问题描述反转一个只有3位数的整数。2.示例输入num=123,输出321,输入num=100,输出1. 3.代码示例3.1python1classSolution:2defreverseInt(self,num):3ifisinstance(num,int)andnum<999andnum>99:4hundreds=int(num/1......
  • 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整
    示例:给定nums=[2,7,11,15],target=9因为nums[0]+nums[1]=2+7=9所以返回[0,1]用数组的indexOf()方法来查找值vartowSum=function(nums,target){for(leti=0,len=nums.length;i<len;i++){if(nums.indexOf(target-nums[i])>-1......
  • 算法~让整数从指定范围开始
    题目有个需求,我有4种类型,每种类型又有自己的数列,问我如何用一个数字来表示它们思路可以看一下java里的线程的实现,它是将一个int64的数字进行分区,每个区间代表一种状态,如运行中,挂起,暂停等,我们也可以通过这个方法来实现。实现在int32中,我找一个范围,存储我的运行中状态的数列,为......
  • 代码随想训练营第三十九天(Python)| 62.不同路径、63. 不同路径 II、343. 整数拆分
    62.不同路径classSolution:defuniquePaths(self,m:int,n:int)->int:#dp[i][j]代表到达dp[i][j]有多少不同路径dp=[[0]*nfor_inrange(m)]#初始化foriinrange(m):dp[i][0]=1forjinra......
  • 2023-11-22:用go语言,给你一个长度为 n 下标从 0 开始的整数数组 nums。 它包含 1 到 n
    2023-11-22:用go语言,给你一个长度为n下标从0开始的整数数组nums。它包含1到n的所有数字,请你返回上升四元组的数目。如果一个四元组(i,j,k,l)满足以下条件,我们称它是上升的:0<=i<j<k<l<n且nums[i]<nums[k]<nums[j]<nums[l]。输入:nums=[1,3,2,......
  • [7] 整数反转
    /***@param{number}x*@return{number}*/varreverse=function(x){letresult=0;letp=1;if(x<0){x=-x;p=-1;}while(x>0){letpop=x%10;x=Math.floor(x/10);if(result>......
  • input如何校验数字为正整数位数与小数位数
    1.表单中内容为<el-form><el-form-item:prop="minPrice":rules="{required:true,validator:PriceValidator,trigger:'blur',}"><el-inputtype="Number"min="1"v-model="......
  • 关注潜在的整数越界问题
    在平时的开发过程中,整数越界是一个容易被忽视的问题,关注潜在的整数越界问题可使我们编写的代码更加健壮,规避因整数越界导致的bug。比较器以下是在CodeReview中发现的比较器实现:乍一看该比较器实现不存在问题,但是如果tag1=Integer.MIN_VALUE=-2147483648,tag2为大于......
  • C语言基础实例:两个整数相加
    使用 scanf() 来接收输入, printf() 与 %d 格式化输出整数。运行实例实例#include<stdio.h>intmain(){ intfirstNumber,secondNumber,sumOfTwoNumbers;printf("输入两个数:"); scanf("%d%d",&firstNumber,&secondNumber);sumOfTwoNumbers=fir......
  • 【pwn】[FSCTF 2023]2str --整数溢出绕过
    检查一下保护状态接着ida看代码逻辑看func函数第一次看真没发现有什么漏洞,题目给了backdoor,虽然strlen可以\x00绕过,但是strcpy函数也限制漏洞的实现。仔细看的话,会发现v3的类型是 unsigned__int8v3;说明v3是一个字节来表示的,可表示的范围只有0~255,那这样绕过思路就很清......