HDU 5936 Difference(折半搜索(中途相遇法))
Posted 谦谦君子,陌上其华
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5936 Difference(折半搜索(中途相遇法))相关的知识,希望对你有一定的参考价值。
http://acm.hdu.edu.cn/showproblem.php?pid=5936
题意:
定义了这样一种算法,现在给出x和k的值,问有多少个y是符合条件的。
思路:
y最多只有10位,再多x就是负的了。
这样的话可以将y分为前后两部分,我们先枚举后5位的情况,然后再枚举前5位的情况,通过二分查找找到匹配的项,这样就大大的降低了时间复杂度。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<vector> 6 #include<stack> 7 #include<queue> 8 #include<cmath> 9 #include<map> 10 #include<set> 11 using namespace std; 12 typedef long long ll; 13 const int INF = 0x3f3f3f3f; 14 const int maxn=100000+5; 15 16 int p[15][15]; 17 int sum[maxn]; 18 int num[maxn]; 19 int x, k,cnt; 20 21 void init() //处于后5位的情况,i是枚举,sum[i]存储的是对应k下的值 22 { 23 cnt=0; 24 memset(sum,0,sizeof(sum)); 25 for(int i=1;i<100000;i++) 26 { 27 int tmp=i; 28 while(tmp) 29 { 30 sum[i]+=p[tmp%10][k]; 31 tmp/=10; 32 } 33 num[cnt++]=sum[i]-i; 34 } 35 sort(num,num+cnt); 36 } 37 38 void solve() //枚举前5位的值,然后二分查找即可 39 { 40 ll ans=0; 41 for(int i=0;i<100000;i++) 42 { 43 ll tmp=sum[i]-(ll)i*100000; 44 int idx=lower_bound(num,num+cnt,x-tmp)-num; 45 while(num[idx]==x-tmp && idx<cnt) 46 { 47 ans++; 48 idx++; 49 } 50 } 51 printf("%lld\\n",ans); 52 } 53 54 int main() 55 { 56 //freopen("in.txt","r",stdin); 57 for(int i=1;i<10;i++) //预处理i^j的值 58 { 59 p[i][0]=1; 60 for(int j=1;j<10;j++) 61 p[i][j]=p[i][j-1]*i; 62 } 63 int T; 64 int kase=0; 65 scanf("%d",&T); 66 while(T--) 67 { 68 printf("Case #%d: ",++kase); 69 scanf("%d%d",&x,&k); 70 init(); 71 solve(); 72 } 73 return 0; 74 }
以上是关于HDU 5936 Difference(折半搜索(中途相遇法))的主要内容,如果未能解决你的问题,请参考以下文章
HDU 5936 Difference 中途相遇法(中国大学生程序设计竞赛(杭州))
HDU 5936 Difference(思维+二分)——2016年中国大学生程序设计竞赛(杭州)