Hash思想:映射

来源:互联网 发布:inpho软件好学吗 编辑:程序博客网 时间:2024/06/06 00:41

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 <= 1000while (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 500000int Hash[1000001];//数据量大,使用全局,下次使用清空int main(){#ifdef ONLINE_JUDGE#elsefreopen("E:\\in.txt", "r", stdin);#endifint 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号书321 */  #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); #endifint L[MAXLEN];int l, m;while (scanf ("%d%d", &l, &m) != EOF){for (int i = 0; i <= l; i++){ //注意i的范围是i<=l not i<lL[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:zureturn 0; }






0 0