hdu_1128

/* 哈希(hash,散列): 一种以空间换取时间的经典算法。
              是依据关键码值(Key Value)而直接进行访问的数据结构。
              把Key Value转换成数据在空间中的地址,以数组为例,就是转换成下标引用。
              在查找时,到对应地址直接去读取就行。
  解决冲突:
     (1)一个好的散列函数值应尽可能平均分布,负载因子(浪费的空间比例)应尽量小。
     (2)线性探查法:冲突后,线性向前试探,找到近期的一个空位置。简单,但缺点是容易产生堆积现象。
     (3)双散列函数法:当位置d冲突后,利用第二个hash函数产生一个与桶容量互质的数c,依次探查(d+c*i)%m

     总思想:把元素值转换成地址,直接到相应地址位置去读取元素。

     题意: 找出[1,1000000]范围内的所有自私数。自私数:找不出任意一个这样数:"数据本身"加上"各个数位"的和 等于它。
     解题思想: 综合运用素数筛选+hash

     坑: 用C提交TLE, 用G++提交AC
*/

#include <stdio.h>
#include <string.h>
#define MAX 1000005
int hash[MAX]; //存储对应位置所代表的数 是否为 自私数:0代表是,1代表不是。
void fun(int n){
   //产生器产生结果=本身+各个数位
   int sum = n;
   while(n){
     sum +=n%10;
     n /=10;
   }
   hash[sum]=1;
}

int main(){
  memset(hash,0,sizeof(hash)); //初始化为0,代表都是自私数
  /*
  for(int i=1;i<MAX;i++){
    //用产生器去筛选出 非自私数
    fun(i);
  }
  //经过上面的筛选,剩下的就是自私数
  for(int i=1;i<MAX;i++){
    if(!hash[i]){
        printf("%d\n",i);
    }
  }
  */

  //优化一下,把上面两个for循环合并一下
  for(int i=1;i<MAX;i++){
     fun(i);
     if(!hash[i]){
        printf("%d\n",i);
     }
  }

  return 0;
}



猜你喜欢

转载自blog.csdn.net/xxf_is_girl_gad/article/details/80660270