目录
思路
样例解释
AC代码
思路
要做出这道题必须直到除留余数法和平方探测法的原理。
除此之外有两个注意点:
1. 在查找时,如果当前位置上不是要找的数会继续找下去(如果k没超过表长的话),但是如果当前位置上是0,说明表里就是没有这个数,不必再往下找。
2. 在存储时,k的取值范围是[0,Tsize)而在查找时是[0,Tsize],我认为后者也应该是左闭右开,但是要做出这道题就得按照它的规则。
样例解释
表长4不是一个素数,取大于4的第一个素数5作为表长。
有table[5] = {0,0,0,0,0}
对于10:10%5 == 0,table[0]是空的,可以插入,更新table[5] = {10,0,0,0,0}
对于6:6%5 == 1,table[1]是空的,可以插入,更新table[5] = {10,6,0,0,0}
对于4:4%5 == 4,table[4]是空的,可以插入,更新table[5] = {10,6,0,0,4}
对于15:15%5 == 0,table[0]非空,(15+1^2)%5 == 1,table[1]非空,(15+2^2)%5 == 4,table[4]非空,(15+3^2)%5 == 4,(15+4^2)%5 == 1,4已经是表长减一,所以插不进去了。
对于11:11%5 == 1,table[1]非空,(11+1^2)%5 == 2,table[2]是空的。更新table[5] = {10,6,11,0,4}。
最终的存储情况是 {10,6,11,0,4}。
下面开始查询
对于11:11%5 == 1 ,table[1]存储的是6,(11+1^2)%5 == 2,table[2]存储的是11,2次找到。
对于4:4%5 == 4,table[4]存储的是4,1次找到。
对于15:15%5 == 0,没找到,(15+1^2)%5 == 1,没找到,(15+2^2)%5 == 4,没找到,(15+3^2)%5 == 4,没找到,(15+4^2)%5 == 1,没找到,5次。(更正,根据题意应该再加一次(15+5^2)%5 == 0,没找到)
对于2:2%5 == 2,没找到,(2+1^2)%5 == 3,没找到,注意3号位存储的为空,不必再往下找了。2次。
共计11次。
AC代码
#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<stack>
#include<cmath>using namespace std;const int maxn = 1010;bool isPrime(int x){if(x==1)return false;for(int i=2;i<=sqrt(x);i++){if(x%i==0)return false;}return true;
}int main(){ int Tsize,inN,outN;cin>>Tsize>>inN>>outN;if(isPrime(Tsize)==false){while(isPrime(Tsize)==false){Tsize ++;}}int Table[Tsize] = {0}; while(inN--){int x;cin>>x;int k;for(k=0;k<Tsize;k++){int idx = (x+k*k)%Tsize;if(Table[idx]==0){Table[idx] = x; break;}}if(k==Tsize)printf("%d cannot be inserted.\n",x);}int tt = 0;//total timefor(int i=0;i<outN;i++){int x;cin>>x;for(int k=0;k<=Tsize;k++){tt ++;int idx = (x+k*k)%Tsize;if(Table[idx]==x||Table[idx]==0)break; }}printf("%.1f",tt*1.0/outN);return 0;
}