Uva1152 查找优化的四种方法 中途相遇法

//查找的方法现在学习了四种,一种是set判重,基于红黑树,对于少量数据还行,大量数据insert很费时间,严重超时的节奏;另外一维遍历查找基于顺序结构,复杂度o(n)

;之后是二分查找,先sort再二分,复杂度o(logn);然后是哈希查找,复杂度o(1),注意哈希表的哈希函数


//Uva1152  用哈希查找的时候处理负数下标不知道怎么处理,算了,wa加TLe

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=4000+5;
const int mx=1000000;
int head[mx],next1[mx];
int shz1[maxn],shz2[maxn],shz3[maxn],shz4[maxn],a,b;

//三重遍历加set.count()查找 插入很耗时

//三重遍历加一重遍历查找 复杂度O(n^4)
void a1(){
    int t=0;
    for(int i=0;i<b;i++){
        for(int j=0;j<b;j++){
            for(int k=0;k<b;k++){
                for(int x=0;x<b;x++){
                    if(-shz1[i]-shz2[j]-shz3[k]+shz4[x]==0)t++;
                }
            }
        }
    }
    cout<<t<<endl;
}

//三重遍历加二分查找    复杂度n^3*logn
int ts(int i){
    sort(shz4,shz4+b);
    int x=0,y=b;
    while(x<y){
        int m=x+(y-x)/2;
        if(shz4[m]==i)return 1;
        else if(shz4[m]>i)y=m;
        else if(shz4[m]<i)x=m+1;
    }
    return 0;
}
void a2(){
    int t=0;
    for(int i=0;i<b;i++){
        for(int j=0;j<b;j++){
            for(int k=0;k<b;k++){
                if(ts(-shz1[i]-shz2[j]-shz3[k])){
                    t++;
                }
            }
        }
    }
    cout<<t<<endl;
}

//三重遍历加哈希查找    复杂度n^3
int hs(int i){
    return abs(i*2%1000000);
}
int ts1(int i){
    int v=hs(i);
    int u=head[v];
    while(u){
        if(u==i)return 1;
        u=next1[u];
    }
    return 0;
}
void a3(){
    cin>>b;
    memset(head,0,sizeof(head));//初始化链头
    for(int i=0;i<b;i++){
        cin>>shz1[i]>>shz2[i]>>shz3[i]>>shz4[i];
        
        //shz4[i] 插入到哈希表
        int jud=0;
        int v=hs(shz4[i]);
        int u=head[v];
        while(u){
            if(u==shz4[i]){
                jud=1;
                break;
            }
            u=next1[u];
        }
        if(!jud){
            next1[shz4[i]]=head[v];
            head[v]=shz4[i];
        }
    }
    
    int t=0;
    for(int i=0;i<b;i++){
        for(int j=0;j<b;j++){
            for(int k=0;k<b;k++){
                if(ts1(-shz1[i]-shz2[j]-shz3[k]))t++;
            }
        }
    }
    cout<<t<<endl;
}

//优化,二重遍历加哈希查找   复杂度n^2
void a4(){
    int t=0;
    memset(head,0,sizeof(head));
    for(int i=0;i<b;i++){
        for(int j=0;j<b;j++){
            int x=shz1[i]+shz2[j];
            int v=hs(x);
            int u=head[v];
            int jud=0;
            while(u){
                if(u==x){
                    jud=1;
                    break;
                }
                u=next1[u];
            }
            if(!jud){
                next1[x]=head[v];
                head[v]=x;
            }
        }
    }
    for(int i=0;i<b;i++){
        for(int j=0;j<b;j++){
            int x=shz3[i]+shz4[j];
            int v=hs(x);
            int u=head[v];
            while(u){
                if(u==x){
                    t++;
                    break;
                }
                u=next1[u];
            }
        }
    }
    cout<<t<<endl;
}
int main(){
    cin>>a;
    while(a--){
        cin>>b;
        for(int i=0;i<b;i++){
            cin>>shz1[i]>>shz2[i]>>shz3[i]>>shz4[i];
        }        
        a4();
        if(a)cout<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值