On Hash
一、最常用——恒等变换
题目描述
N个读者依次编号为1,2,…,N,把M本书依次编号为1,2,…,M。同时,按照“臭味相投”的原则,和你喜欢读同一本书的人,就是你的潜在朋友。你现在的任务是从这份借阅记录中计算出每个人有几个潜在朋友。
输入格式
每个案例第一行两个整数N,M,2 <= N ,M<= 200。接下来有N行,第i(i = 1,2,…,N)行每一行有一个数,表示读者i-1最喜欢的图书的编号P(1<=P<=M)。
输出格式
每个案例包括N行,每行一个数,第i行的数表示读者i有几个潜在朋友。如果i和任何人都没有共同喜欢的书,则输出“BeiJu”(即悲剧,^ ^)。
代码
#include <iostream> using namespace std; int main() { int n,m; while(scanf("%d %d",&n,&m)!=EOF){ int stu[200]; int book[200]={0}; for(int i=0;i<n;i++){ scanf("%d",&stu[i]); int temp = stu[i]; book[temp] ++; } for(int i=0;i<n;i++){ int temp = stu[i]; if(book[temp]>1){ printf("%d\n",book[temp]-1); } else{ printf("BeiJu\n"); } } } return 0; }
PS:时间复杂度为O(n),其中book数组使用了恒等变换的思想。
二、容器的合理使用
虽然在hash这块有很多算法能够使用,但是不能一昧地盲目套用,往往会事倍功半。这里重点注意map容器,往往能够很简单地解决统计问题。
下面以一个题为例。
题目描述
Being unique is so important to people on Mars that even their lottery is designed in a unique way. The rule of winning is simple: one bets on a number chosen from [1, 104]. The first one who bets on a unique number wins. For example, if there are 7 people betting on 5 31 5 88 67 88 17, then the second one who bets on 31 wins.
输入
Each input file contains one test case. Each case contains a line which begins with a positive integer N (<=105) and then followed by N bets. The numbers are separated by a space.
输出
For each test case, print the winning number in a line. If there is no winner, print "None" instead.
代码
第一次思路:
#include <iostream> using namespace std; int main() { int num; while(scanf("%d",&num)!=EOF){ int a[10010]={0}; int flag=0; int maxn = 0; int times =1; if(num==1){ int temp; scanf("%d",&temp); printf("%d\n",temp); continue; } for(int i=0;i<num;i++){ int temp; scanf("%d",&temp); a[temp] ++; maxn = maxn>temp? maxn:temp; if(a[temp]>1){ a[temp] = 0; } else{ a[temp] = times; times++; } } int mark; int minn = times; for(int i=0;i<maxn;i++){ if(a[i]<=minn&&a[i]>0){ minn = a[i]; mark=i; flag=1; } } if(flag==0) printf("None\n"); else printf("%d\n",mark); } return 0; }
改进思路:
#include <iostream> #include <vector> #include <unordered_map> #include <cstdio> using namespace std; int main(){ int num; while(scanf("%d",&num)!=EOF){ int flag=0; vector<int> seq; unordered_map<int,int> nlog; for(int i=0;i<num;i++){ int temp; scanf("%d",&temp); nlog[temp] ++; seq.push_back(temp); } for(vector<int>::iterator it=seq.begin();it!=seq.end();it++){ if(nlog[*it]==1){ printf("%d\n",*it); flag=1; break; } } if(flag==0) printf("None\n"); } }
孰简孰繁一目了然。
浙公网安备 33010602011771号