题目描述:给出n棵树的高度,每棵树上都站着一只鸟,枪手Jack站在最左边那棵树的左边对鸟进行射击,当Jack在高度为H的地方向右发射一颗子弹的时候,高度为H的树上的鸟儿就会掉落(注:其他树上的鸟儿不会飞走或掉落,这不是脑经急转弯!)。Jack会射击多次,他想知道每次射击会有多少鸟儿掉落下来。

思路:题意十分清晰,思路也很简单,只要实现这种映射关系就行了,数据量比较大。

方法1:map+IO外挂水之

 1 #include <cstdio>
 2 #include <cctype>
 3 #include <map>
 4 using namespace std;
 5
 6 map<int, int> mp;
 7 int n, m, tmp;
 8 char buffer[10];
 9
10 void print_d( int x )
11 {
12     if ( x == 0 )
13     {
14         putchar('0');
15     }
16     else
17     {
18         int p = 0;
19         while ( x )
20         {
21             buffer[p++] = x % 10 + '0';
22             x = x / 10;
23         }
24         for ( int i = p - 1; i >= 0; i-- )
25         {
26             putchar(buffer[i]);
27         }
28     }
29     putchar('\n');
30 }
31
32 void scan_d( int & x )
33 {
34     char ch = getchar();
35     while ( !isdigit(ch) ) ch = getchar();
36     x = 0;
37     do
38     {
39         x = x * 10 + ch - '0';
40         ch = getchar();
41     } while ( isdigit(ch) );
42 }
43
44 int main ()
45 {
46     while ( scanf("%d%d", &n, &m) != EOF )
47     {
48         mp.clear();
49         while ( n-- )
50         {
51             scan_d(tmp);
52             mp[tmp]++;
53         }
54         while ( m-- )
55         {
56             scan_d(tmp);
57             print_d(mp[tmp]);
58             mp[tmp] = 0;
59         }
60     }
61     return 0;
62 }

这样写完全是对的,不过比csc的代码要慢一点,原因如下:

当调用mp[tmp]的时候,如果tmp在map中不存在,则默认会插入一个tmp到0的映射然后返回,所以这样写会让节点数增多,查询效率变低。

证明代码如下:

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <map>
 4 using namespace std;
 5
 6 int main ()
 7 {
 8     map<int, int> mp;
 9     cout << "mp is empty: " << mp.size() << endl;
10     cout << mp[111] << endl;
11     cout << "The size is: " << mp.size() << endl;
12     cout << mp[222] << endl;
13     cout << "The size is: " << mp.size() << endl;
14     for ( map<int, int>::iterator it = mp.begin(); it != mp.end(); it++ )
15     {
16         cout << it->first << " maps into " << it->second << endl;
17     }
18     system("pause");
19     return 0;
20 }

运行结果如下:

可见确实是这样,因此可以这样写来加快效率:

 1 #include <cstdio>
 2 #include <map>
 3 using namespace std;
 4
 5 map<int, int> mp;
 6 int n, m, tmp;
 7
 8 int main ()
 9 {
10     while ( scanf("%d%d", &n, &m) != EOF )
11     {
12         mp.clear();
13         while ( n-- )
14         {
15             scanf("%d", &tmp);
16             mp[tmp]++;
17         }
18         while ( m-- )
19         {
20             scanf("%d", &tmp);
21             if ( mp.count(tmp) )
22             {
23                 printf("%d\n", mp[tmp]);
24                 mp.erase(tmp);
25             }
26             else
27             {
28                 printf("0\n");
29             }
30         }
31     }
32     return 0;
33 }

不过实测差不多,关键可能还是hdu服务器不稳定吧,不过mp[tmp] = 0; 还是没有 mp.erase(tmp); 好,前者删除节点,后者只是修改映射的值,前者配合mp.count(tmp)理论上更胜一筹。

方法2:二分 略...

方法3:hash

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4
 5 const int N = 5000007;
 6 int hash_table[N];
 7 int cnt[N];
 8 int n, m, tmp;
 9
10 int hash_key( int key )
11 {
12     return key % N;
13 }
14
15 int kth( int k )
16 {
17     int r = ( k + 1 ) >> 1;
18     if ( k & 1 ) return r * r;
19     return -r * r;
20 }
21
22 void insert( int key )
23 {
24     int t = hash_key(key);
25     for ( int i = 0; ; i++ )
26     {
27         int pos = t + kth(i);
28         if ( pos < 0 ) pos += N;
29         if ( pos >= N ) pos -= N;
30         if ( hash_table[pos] == -1 )
31         {
32             hash_table[pos] = key;
33             cnt[pos]++;
34             return ;
35         }
36         else if ( hash_table[pos] == key )
37         {
38             cnt[pos]++;
39             return ;
40         }
41     }
42 }
43
44 int find( int key )
45 {
46     int t = hash_key(key);
47     for ( int i = 0; ; i++ )
48     {
49         int pos = t + kth(i);
50         if ( pos < 0 ) pos += N;
51         if ( pos >= N ) pos -= N;
52         if ( hash_table[pos] == key )
53         {
54             int r = cnt[pos];
55             cnt[pos] = 0;
56             return r;
57         }
58         else if ( hash_table[pos] == -1 )
59         {
60             return 0;
61         }
62     }
63 }
64
65 int main ()
66 {
67     while ( scanf("%d%d", &n, &m) != EOF )
68     {
69         memset( hash_table, -1, sizeof(hash_table) );
70         memset( cnt, 0, sizeof(cnt) );
71         while ( n-- )
72         {
73             scanf("%d", &tmp);
74             insert(tmp);
75         }
76         while ( m-- )
77         {
78             scanf("%d", &tmp);
79             printf("%d\n", find(tmp));
80         }
81     }
82     return 0;
83 }

转载于:https://www.cnblogs.com/huoxiayu/p/4393062.html

hdu 5199 map或二分或哈希相关推荐

  1. 【loj2073】「JSOI2016」扭动的回文串(manacher+二分+双哈希)

    manachermanachermanacher+二分+双哈希 看见标题就不想做的童鞋可以看下面,让你更绝望. 这题思路比较简单明了,我们就按照题目说的那样,设串TTT为答案,分两种情况讨论: 当TT ...

  2. LeetCode 244. 最短单词距离 II(哈希map+set二分查找)

    文章目录 1. 题目 2. 解题 2.1 暴力超时 2.2 哈希表+set二分查找 1. 题目 请设计一个类,使该类的构造函数能够接收一个单词列表. 然后再实现一个方法,该方法能够分别接收两个单词 w ...

  3. hdu 5199 Gunner(STL之map,水)

    Problem Description Long long ago, there is a gunner whose name is Jack. He likes to go hunting very ...

  4. HDU 3973 AC's String 字符串哈希

    HDU 3973 通过哈希函数将一个字符串转化为一个整数,通过特定的方式可以使得这个哈希值几乎没有冲突(这就是关键之处,几乎没有视为没有= =!, 其实也可以考虑实现哈希冲突时的处理,只是这道题没必要 ...

  5. HDU 3646 DP + 二分

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=3646 题意:你有N把武器,每把武器可以对敌人造成一定的伤害(et:攻击力500,敌人血量为200,杀死敌人 ...

  6. stl 基于哈希的map c++_关于哈希表,你该了解这些!

    (给算法爱好者加星标,修炼编程内功) 来源:代码随想录(本文来自作者投稿) 哈希表 首先什么是 哈希表,哈希表(英文名字为Hash table,国内也有一些算法书籍翻译为散列表,大家看到这两个名称知道 ...

  7. 学习笔记:C++进阶【继承、多态、二叉树进阶、map和set、哈希、C++11、异常、智能指针、特殊类设计、C++的类型转换】

    文章目录 前言 一.继承 1. 继承的概念及定义 1.1 继承的概念 1.2 继承的定义 1.2.1 定义格式 1.2.2 继承关系和访问限定符 1.2.3 继承基类成员访问方式的变化 2. 基类和派 ...

  8. HDU 6231 K-th Number(二分)

    题目链接:点击打开链接 题意:从原序列A中所有长度大于K的子序列中选取第K大的数组成新序列B,输出B中第M大数. 这题不是看题解说是二分完全想不到,一直在想有没有什么数据结构可以维护.其实即使知道二分 ...

  9. HDU 2289 Cup(二分+圆台体积)

    Problem Description The WHU ACM Team has a big cup, with which every member drinks water. Now, we kn ...

最新文章

  1. 如何优雅的使用Mock Server
  2. 上传Jar到本地Maven仓库
  3. c语言输入不为空时循环,scanf循环输入的时候第二个数据输入有问题,相当于是多出来的...
  4. 公司想申请网易企业电子邮箱,怎么样?
  5. 团队二阶段冲刺个人工作总结2
  6. paypal创建订单后怎么获得id_5步创建Facebook商店(最新版教程)学习如何在Facebook上卖货...
  7. TreeView 数据库绑定实例
  8. ActiveMq笔记3-AMQ高可用性理论
  9. 发改委:扩大优质民营企业债券发行规模
  10. atitit.自适应设计悬浮图片的大小and 位置
  11. 苹果手机如何上传文件到服务器,有限条件下,如何将IPhone手机照片传到Windows电脑中?...
  12. 微商城是什么?如何制作一个微商城
  13. MySQL单表数据量大优化方案及注意事项
  14. Lecture05:随机市场出清
  15. 技术支持快递第6 期
  16. iou(交并比)的概念
  17. 2020考研上海交通大学823计算机通信网真题回忆
  18. 组合数学(洛谷P5148)
  19. 学会重构与对比 ——码农鼻祖天才香农
  20. 代码分享 | EEG数据的等效偶极子源定位

热门文章

  1. 银行推出一年存1万连着存5年,利率4.5%,能存吗?
  2. android+主界面所有应用程序图标添加统一背景主题,Android 4.0替Launcher主界面所有应用程序图标添加统一背景主题...
  3. 重庆大学计算机组成,重庆大学计算机组成原理试题集(含部分答案)
  4. 1650显卡学计算机,适合老电脑升级?GTX1650显卡开箱,性价比依然不高!
  5. python语言及其应用电子版翁正秋_Python语言及其应用pdf
  6. Java 调用 Caffe_解决 free(): invalid pointer: 0x00000000019ff700 运行时报错(caffe)(libtool使用)...
  7. 程序员如何跟领导提离职_如何优雅地跟老板提加薪?按照这3个步骤来,也不是什么难事...
  8. imp oracle full,Oracle 10g imp 之 full database (转官档)
  9. 前端面试系列-JS 异步编程
  10. 23种设计模式----------代理模式(一)