• HDU 3833 YY's new problem (hash)


    YY's new problem

    Time Limit: 12000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 3158    Accepted Submission(s): 890


    Problem Description
    Given a permutation P of 1 to N, YY wants to know whether there exists such three elements P[i1], P[i2], P[i3] that 
    P[i1]-P[i2]=P[i2]-P[i3], 1<=i1<i2<i3<=N.
     
    Input
    The first line is T(T<=60), representing the total test cases.
    Each test case comes two lines, the former one is N, 3<=N<=10000, the latter is a permutation of 1 to N.
     
    Output
    For each test case, just output 'Y' if such i1, i2, i3 can be found, else 'N'.
     
    Sample Input
    2 3 1 3 2 4 3 2 4 1
     
    Sample Output
    N Y
     
    Source
     
    Recommend
    xubiao

    一是利用二级排序,二是利用hash表。先说说hash表吧。既然要找到1到n序列中是否存在满足题意的三个元素,注意这三个元素有先后顺序之分,可以用一个数组来模拟。首先将数组全部清0,然后开始读入元素i,每读入一个元素就将以该元素为下标的hash表中的元素加1,即hash[i]++,然后在hash表中寻找,在hash[i]的对称的前面和后面查找,如果hash[i-j]+hash[i+j]==1, 说明在i出现时,有两种可能,一是比i小的数已经出现但比i大的数还没出现,或者比i大的数已经出现,比i小的数还没出现,没出现的数在i的后面,已经出现的在i的前面,这就找到了满足题意的序列。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    int n,hash[20010];
    
    int main(){
    
        //freopen("input.txt","r",stdin);
    
        int t;
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            memset(hash,0,sizeof(hash));
            int flag=0,x;
            for(int k=1;k<=n;k++){
                scanf("%d",&x);
                hash[x]++;
                if(flag==0){
                    for(int i=1;i<x && i+x<=n;i++)
                        if(hash[x-i]+hash[x+i]==1){
                            flag=1;
                            break;
                        }
                }
            }
            if(flag)
                printf("Y\n");
            else
                printf("N\n");
        }
        return 0;
    }

    这个算法应用范围更广:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    int n,num[10010];
    
    int main(){
    
        //freopen("input.txt","r",stdin);
    
        int t;
        scanf("%d",&t);
        while(t--){
            scanf("%d",&n);
            int x;
            for(int i=1;i<=n;i++){
                scanf("%d",&x);
                num[x]=i;
            }
            int lim=2*(n-1),flag=0;
            for(int i=4;i<=lim && !flag;i+=2){
                for(int j=(i>n?i-n:1);j<(i>>1);j++){
                    int k=i-j;
                    if((num[j]-num[i>>1])*(num[i>>1]-num[k])>0){
                        flag=1;
                        break;
                    }
                }
            }
            if(flag)
                printf("Y\n");
            else
                printf("N\n");
        }
        return 0;
    }
  • 相关阅读:
    VI与VIM区别
    所有的 Unix Like 系统都会内建 vi 文书编辑器。vim 是vi的升级版本,它不仅兼容vi的所有指令 ,而且还有一些新的特性在里面。
    串口bmc
    sed常用
    echo -n -e "请输入重启间隔的时间(分钟): "
    reboot 就是 poweroff 然后power on
    rpm -ql BackupPC |grep etc
    Linux压力测试软件Stress安装及使用指南2
    stress工具使用指南和结果分析(好好好测试通过)
    告别烧脑,金融保险企业邮件应该这样卖产品!
  • 原文地址:https://www.cnblogs.com/jackge/p/3094662.html
Copyright © 2020-2023  润新知