hdu 5199 map或二分或哈希
题目描述:给出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或二分或哈希相关推荐
- 【loj2073】「JSOI2016」扭动的回文串(manacher+二分+双哈希)
manachermanachermanacher+二分+双哈希 看见标题就不想做的童鞋可以看下面,让你更绝望. 这题思路比较简单明了,我们就按照题目说的那样,设串TTT为答案,分两种情况讨论: 当TT ...
- LeetCode 244. 最短单词距离 II(哈希map+set二分查找)
文章目录 1. 题目 2. 解题 2.1 暴力超时 2.2 哈希表+set二分查找 1. 题目 请设计一个类,使该类的构造函数能够接收一个单词列表. 然后再实现一个方法,该方法能够分别接收两个单词 w ...
- hdu 5199 Gunner(STL之map,水)
Problem Description Long long ago, there is a gunner whose name is Jack. He likes to go hunting very ...
- HDU 3973 AC's String 字符串哈希
HDU 3973 通过哈希函数将一个字符串转化为一个整数,通过特定的方式可以使得这个哈希值几乎没有冲突(这就是关键之处,几乎没有视为没有= =!, 其实也可以考虑实现哈希冲突时的处理,只是这道题没必要 ...
- HDU 3646 DP + 二分
链接:http://acm.hdu.edu.cn/showproblem.php?pid=3646 题意:你有N把武器,每把武器可以对敌人造成一定的伤害(et:攻击力500,敌人血量为200,杀死敌人 ...
- stl 基于哈希的map c++_关于哈希表,你该了解这些!
(给算法爱好者加星标,修炼编程内功) 来源:代码随想录(本文来自作者投稿) 哈希表 首先什么是 哈希表,哈希表(英文名字为Hash table,国内也有一些算法书籍翻译为散列表,大家看到这两个名称知道 ...
- 学习笔记:C++进阶【继承、多态、二叉树进阶、map和set、哈希、C++11、异常、智能指针、特殊类设计、C++的类型转换】
文章目录 前言 一.继承 1. 继承的概念及定义 1.1 继承的概念 1.2 继承的定义 1.2.1 定义格式 1.2.2 继承关系和访问限定符 1.2.3 继承基类成员访问方式的变化 2. 基类和派 ...
- HDU 6231 K-th Number(二分)
题目链接:点击打开链接 题意:从原序列A中所有长度大于K的子序列中选取第K大的数组成新序列B,输出B中第M大数. 这题不是看题解说是二分完全想不到,一直在想有没有什么数据结构可以维护.其实即使知道二分 ...
- HDU 2289 Cup(二分+圆台体积)
Problem Description The WHU ACM Team has a big cup, with which every member drinks water. Now, we kn ...
最新文章
- 如何优雅的使用Mock Server
- 上传Jar到本地Maven仓库
- c语言输入不为空时循环,scanf循环输入的时候第二个数据输入有问题,相当于是多出来的...
- 公司想申请网易企业电子邮箱,怎么样?
- 团队二阶段冲刺个人工作总结2
- paypal创建订单后怎么获得id_5步创建Facebook商店(最新版教程)学习如何在Facebook上卖货...
- TreeView 数据库绑定实例
- ActiveMq笔记3-AMQ高可用性理论
- 发改委:扩大优质民营企业债券发行规模
- atitit.自适应设计悬浮图片的大小and 位置
- 苹果手机如何上传文件到服务器,有限条件下,如何将IPhone手机照片传到Windows电脑中?...
- 微商城是什么?如何制作一个微商城
- MySQL单表数据量大优化方案及注意事项
- Lecture05:随机市场出清
- 技术支持快递第6 期
- iou(交并比)的概念
- 2020考研上海交通大学823计算机通信网真题回忆
- 组合数学(洛谷P5148)
- 学会重构与对比 ——码农鼻祖天才香农
- 代码分享 | EEG数据的等效偶极子源定位
热门文章
- 银行推出一年存1万连着存5年,利率4.5%,能存吗?
- android+主界面所有应用程序图标添加统一背景主题,Android 4.0替Launcher主界面所有应用程序图标添加统一背景主题...
- 重庆大学计算机组成,重庆大学计算机组成原理试题集(含部分答案)
- 1650显卡学计算机,适合老电脑升级?GTX1650显卡开箱,性价比依然不高!
- python语言及其应用电子版翁正秋_Python语言及其应用pdf
- Java 调用 Caffe_解决 free(): invalid pointer: 0x00000000019ff700 运行时报错(caffe)(libtool使用)...
- 程序员如何跟领导提离职_如何优雅地跟老板提加薪?按照这3个步骤来,也不是什么难事...
- imp oracle full,Oracle 10g imp 之 full database (转官档)
- 前端面试系列-JS 异步编程
- 23种设计模式----------代理模式(一)