zoukankan      html  css  js  c++  java
  • hdu 5183. Negative and Positive (哈希表)

    Negative and Positive (NP)

    Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 2177    Accepted Submission(s): 556


    Problem Description
    When given an array (a0,a1,a2,an1) and an integer K, you are expected to judge whether there is a pair (i,j)(0ij<n) which makes that NPsum(i,j) equals to K true. Here NPsum(i,j)=aiai+1+ai+2++(1)jiaj
     

     

    Input
    Multi test cases. In the first line of the input file there is an integer T indicates the number of test cases.
    In the next 2T lines, it will list the data for each test case.
    Each case occupies two lines, the first line contain two integers n and K which are mentioned above.
    The second line contain (a0,a1,a2,an1)separated by exact one space.
    [Technical Specification]
    All input items are integers.
    0<T25,1n1000000,1000000000ai1000000000,1000000000K1000000000
     

     

    Output
    For each case,the output should occupies exactly one line. The output format is Case #id: ans, here id is the data number starting from 1; ans is “Yes.” or “No.” (without quote) according to whether you can find (i,j) which makes PNsum(i,j) equals to K.
    See the sample for more details.
     

     

    Sample Input
    2
    1 1
    1
    2 1
    -1 0
     

     

    Sample Output
    Case #1: Yes. Case #2: No.
    Hint
    If input is huge, fast IO method is recommended.
     

     

    Source
     
     1 #include<stdio.h>
     2 #include<string.h>
     3 typedef long long ll ;
     4 const int mod = 1000000 + 3 ;
     5 int a[mod] ;
     6 ll sum[mod] ;
     7 int n , k ;
     8 
     9 struct edge
    10 {
    11     int nxt ;
    12     int node ;
    13 }e[mod];
    14 int head[mod] , top ;
    15 
    16 void init ()
    17 {
    18     memset (head , 0 , sizeof(head)) ;
    19     top = 0 ;
    20 }
    21 
    22 void insert (ll x)
    23 {
    24     int y = x % mod ;
    25     if (y < 0)
    26         y += mod ;
    27     e[++top].nxt = head[y] ;
    28     e[top].node = x ;
    29     head[y] = top ;
    30 }
    31 
    32 bool find (ll x)
    33 {
    34     int y = x % mod ;
    35     if (y < 0)
    36         y += mod ;
    37     for (int i = head[y] ; i ; i = e[i].nxt) {
    38         if (e[i].node == x)
    39             return true ;
    40     }
    41     return false ;
    42 }
    43 
    44 int main ()
    45 {
    46     //freopen ("a.txt" , "r" , stdin) ;
    47     int T ;
    48     scanf ("%d" , &T) ;
    49     int ans = 0 ;
    50     while (T--) {
    51         scanf ("%d%d" , &n , &k) ;
    52         for (int i = 1 ; i <= n ; i++) {
    53             scanf ("%d" , &a[i]) ;
    54         }
    55         sum[0] = 0 ;
    56         for (int i = 1 ; i <= n ; i++) {
    57             if (i & 1)
    58                 sum[i] = sum[i - 1] + a[i] ;
    59             else
    60                 sum[i] = sum[i - 1] - a[i] ;
    61         }
    62         init () ;
    63         bool flag = 0 ;
    64         for (int i = n ; i > 0 && !flag ; i--) {
    65             insert (sum[i]) ;
    66             ll w ;
    67             if (i & 1)
    68                 w = sum[i - 1] + k ;
    69             else
    70                 w = sum[i - 1] - k ;
    71             if (find (w))
    72                 flag = true ;
    73         }
    74         if (flag)
    75             printf ("Case #%d: Yes.
    " , ++ans ) ;
    76         else
    77             printf ("Case #%d: No.
    " , ++ans ) ;
    78     }
    79     return 0 ;
    80 }
    583ms
     第一次遇到哈希表,它能把查找一个数的复杂度降到0(1) 。
    我学会的那种写法是通过“ 前向星 ”实现的,
    他通过对插入数取余把数字存到数组中,从而防止了carsh , nxt记录的是上一个和当前输入的数 取余 后相等的数 在 数组中的下标。
    这道题思路:
    sum[i] = a0 - a1…… (-1)^n*an ;
    将他们存入哈希表中
    然后从n~1寻找哈希表中是否有sum[i] + k

     ps:另外用lower_bound + sort也能办到

  • 相关阅读:
    一周试用yii开发一个带各种该有功能的web程序(三)
    制作centos的U盘启动盘
    VMware下centos6.3minimal搭建网络环境
    [原]SQLite的学习系列之获取数据库版本
    Android Studio NDK 学习之接受Java传入的字符串
    [原]Ubuntu 14.04编译Android Kernel
    [原]运行编译好的Android模拟器
    [原]编译Android源码过程中遇到的问题
    [原]Android打包之Gradle打包
    [原]Android打包之跨平台打包
  • 原文地址:https://www.cnblogs.com/get-an-AC-everyday/p/4330748.html
Copyright © 2011-2022 走看看