您的位置:首页 > 其它

Hash思想:映射

2014-02-12 18:18 127 查看

1.使用Hash思想题目的特点



1、输入的数据的变化范围是有限的;

比如:

(1)、当读到N=0时输入结束。其中N不超过1000,成绩分数为(包含)0到100之间的一个整数。

(2)、每组测试数据有两行,第一行有两个数n,m(0<n,m<1000000),第二行包含n个各不相同,且都处于区间[-500000,500000]的整数。

(3)、每个案例第一行两个整数N,M,2 <= N ,M<= 200。接下来有N行,第i(i =
1,2,…,N)行每一行有一个数,表示读者i-1最喜欢的图书的编号P(1<=P<=M)

2、能够得到对应关系

(1)、给定分数的人数。定义score[101],score[i]代表了成绩 i 的学生数;

(2)、给你n个整数,请按从大到小的顺序输出其中前m大的数。buf[1000000] 存放出现的数,出现为1,没出现为0.

(3)、。。。

2.题目(5个)



2.1本来不是Hash

但这个代码起始存在问题的。

/**
输入一个数n,然后输入n个数值各不相同,再输入一个值x,
输出这个值在这个数组中的下标(从0开始,若不在数组中则输出-1)。
*/

//----------------------------------------------------
//NB
//但是给的数超过20000就出错了!题目没说数的范围

#include<stdio.h>
#include<memory.h>

void main(){
int n,i,temp,a[20000];
while(~scanf("%d",&n)){
memset(a,-1,sizeof(a));
for(i=0;i<n; a[temp]=i++) //大神的Hash思想
scanf("%d",&temp);

scanf("%d",&temp);
printf("%d\n",a[temp]);
}
}


2.2 题目1018:统计同成绩学生人数

http://ac.jobdu.com/problem.php?pid=1018

#include <stdio.h>

int main(){
int n;
while (scanf ("%d", &n) != EOF && n != 0){
int Hash[101]= {0};

for (int i =1; i <= n; i++){
int x;
scanf("%d", &x);
Hash[x] ++;
}
int x;
scanf("%d", &x);
printf("%d\n", Hash[x]);
}
return 0;
}

#include <stdio.h>

int buf[101]={0}; //存放该成绩的人数,满分 100
/*-----------------------------------------------------
WA:buf声明为全局变量。对于多组数据,在统计下一组数据
时并没有把之前的数据清空,所以出现错误 。

声明为全局变量应该考虑多组数据时是否会变?如果变可以
在下次使用前清空,或者声明为局部变量。一般小数据没有
必要什么为全局。

-----------------------------------------------------*/
int main(){

int n; // n <= 1000
while (scanf ("%d", &n) != EOF && n){
for (int i =0; i < 101; i++){
buf[i] = 0;
}//清空

for (int i = 0; i < n; i++){
int score;
scanf ("%d", &score);
buf[score]++; // 记录该成绩人数
} // Hash思想

int dscore;
scanf ("%d", &dscore); //给定成绩
printf("%d\n", buf[dscore]);
}
return 0;
}


2.3 题目1431:Sort

http://ac.jobdu.com/problem.php?pid=1431

Runtime Error:
1.地址越界:数字大小定义为100,初始化是1000.

#include <stdio.h>
#define OFFSET 500000
int Hash[1000001];	//数据量大,使用全局,下次使用清空
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("E:\\in.txt", "r", stdin);
#endif

int n, m;
while (scanf ("%d %d", &n, &m) != EOF){
for (int i = -500000; i <= 500000; i++){
Hash[i+OFFSET] = 0;
} // 多次测试,清空:0代表未,1出现

for (int i = 0; i < n; i++){
int x;
scanf("%d", &x);
Hash[x+OFFSET] = 1;
} // 标记出现的数

for (int i = 500000; i >= -500000; i--){
if (Hash[i+OFFSET] == 1){
printf("%d", i);
m --;
if (m != 0){
printf(" ");
}
else{
printf("\n");
break;
}//if-else
}// if
}// for
}// while:多组

return 0;
}


2.4 题目1156:谁是你的潜在朋友

http://ac.jobdu.com/problem.php?pid=1156

Runtime Error:
数组没加取址符&:scanf("%d", stu[i]);

/**
* int n(people), m(book);
* the same book
* 每个人有几个潜在的朋友

4  5    //4个人,5本书
2       //1 喜欢 2号书
3
2
1

*/

#include <stdio.h>

int main(){
#ifdef ONLINE_JUDGE
#else
freopen("E:\\in.txt", "r", stdin);
#endif

int n,m;

while (scanf("%d%d", &n, &m) != EOF){
int stu[210]; //book id
int book[210]; // num of stu

for (int i = 1; i <= m; i++){
book[i] = 0;
}// 借书人初为0

for (int i = 1; i <= n; i++){
scanf("%d", &stu[i]); // WA:没加取址符
book[stu[i]]++;//人数+1
}// 读者i喜欢的书号

for (int i = 1; i <= n; i++){
if( book[stu[i]] == 1)
printf("BeiJu\n");//只有自己喜欢
else
printf("%d\n", book[stu[i]] - 1);//去掉自己,就是其他人的数量

}// print

}// while: zu

return 0;
}


2.5 题目1088:剩下的树

http://ac.jobdu.com/problem.php?pid=1088

/**
* Hash思想:有限的取值范围:输入有限的数据,使用的
* 空间有限,可以建立下标对应关系。
*
* int L[10001];共10001个位置
* 有树为1,无为0
* 每输入一个区间[a,b],把【L[a],L[b]】标记为0
* 最后遍历统计1的个数。
*/

#include <stdio.h>

#define MAXLEN 10001
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("E:\\in.txt", "r", stdin);
#endif

int L[MAXLEN];
int l, m;
while (scanf ("%d%d", &l, &m) != EOF){
for (int i = 0; i <= l; i++){ //注意i的范围是i<=l not i<l
L[i] = 1;
}// 初始化,种l+1棵树

int a, b;
for (int i = 1; i <= m; i++){
scanf("%d%d", &a, &b);
for(int j = a; j <= b; j++){
L[j] = 0;
}// 移走
}// m组

int left=0;
for (int i = 0; i <= l; i++){
if (L[i] == 1)
left++;
}
printf("%d\n", left);
}// while:zu
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: