pongo英雄会-幸运数题解
显然我们只要知道1~x范围有多少幸运数(用f(x)表示),lucky(x,y)=f(y)-f(x-1).
解法1. 计算排列数
由于y<=1000000000这个规模,我们不能暴力验证每个数是否是幸运数。可以想到,对于同样的数字组成,不同的数字排列对应不同的幸运数,比如12,21。那么就只需枚举合法的数字组成,算出相应的排列数。设数字i有a[i]个,n=Σa[i],则对应的排列数是n!/∏a[i]!。
接下来就只要枚举那些合法的数字组成了。我们希望枚举时对每位的可取数字是没有限制的,可以分类来进行。下面举例说明。
比如x=2345. 当千位是0或1时,后三位是没有限制的,0~9都可以,可以用递归来枚举a[i],然后结合已确定的千位来判断这种组成是否是幸运数,是的话答案就加上相应的排列数。
当千位等于2时,继续依次固定百位=0,1,2计算。余此类推。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<time.h>
using namespace std; bool isPrime(int n)
{
if(n<2) return false;
int i;
for(i=2;i*i<=n;i++) if(n%i==0) return false;
return true;
} bool check(int cnt[],int n1,int n2)
{
int i;
int s1=n1,s2=n2;
for(i=1;i<10;i++)
{
s1+=i*cnt[i];
s2+=i*i*cnt[i];
}
return isPrime(s1)&&isPrime(s2);
} int fac[10];
void comFactorial()
{
int i;
fac[0]=1;
for(i=1;i<10;i++) fac[i]=fac[i-1]*i;
} int nPermutation(int cnt[])
{
int i;
int n=0;
for(i=0;i<10;i++) n+=cnt[i];
int ans=fac[n];
for(i=0;i<10;i++) ans/=fac[cnt[i]];
return ans;
} void dfs(int digit,int n,int cnt[],int n1,int n2,int &ans)
{
int i;
if(digit==10)
{
cnt[0]=n;
if(check(cnt,n1,n2))
ans+=nPermutation(cnt);
return ;
}
for(i=0;i<=n;i++)
{
cnt[digit]=i;
dfs(digit+1,n-i,cnt,n1,n2,ans);
}
} int com(int x)
{
comFactorial();
int digit[12];
int cnt[12];
int i,j,n=0;
while(x>0)
{
digit[n++]=x%10;
x/=10;
}
int n1=0,n2=0,s1,s2,ans=0;
for(i=n-1;i>0;i--)
{
for(j=0;j<digit[i];j++)
{
s1=n1+j;
s2=n2+j*j;
dfs(1,i,cnt,s1,s2,ans);
}
n1+=digit[i];
n2+=digit[i]*digit[i];
}
for(i=0;i<=digit[0];i++)
{
s1=n1+i;
s2=n2+i*i;
if(isPrime(s1)&&isPrime(s2)) ans++;
}
return ans;
} int lucky(int x,int y)
{
return com(y)-com(x-1);
}
解法2. dp
dp[n][s1][s2]表示n位,各位数字的和为s1,平方和为s2的方法数。根据第一位的数字来状态转移,dp[n][s1][s2]=Σdp[n-1][s1-i][s2-i*i] i=0...9
两种方法的共同之处是都要逐渐固定高位来分类计算。
#include <cstring>
#include <vector>
#include <iostream>
#include <set>
#include <map>
#include <algorithm>
#include<deque>
#include<cstdio>
#include<time.h>
using namespace std; int dp[12][82][730]; bool isPrime(int n)
{
int i;
if(n<2) return false;
for(i=2;i*i<=n;i++) if(n%i==0) return false;
return true;
} int f(int n,int s1,int s2)
{
if(dp[n][s1][s2]!=-1) return dp[n][s1][s2];
if(n==1)
{
if(s1<10&&s1*s1==s2) return dp[n][s1][s2]=1;
else return dp[n][s1][s2]=0;
}
else
{
int i;
int ans=0;
for(i=0;i<10&&i<=s1&&i*i<=s2;i++) ans+=f(n-1,s1-i,s2-i*i);
return dp[n][s1][s2]=ans;
}
} int com(int x)
{
int a[20];
int num=0;
while(x>0)
{
a[num++]=x%10;
x/=10;
}
int ans=0;
int i,j,k,m;
int s1=0,s2=0;
int p1=0,p2=0;
for(k=num-1;k>0;k--)
{
for(m=0;m<a[k];m++)
{
s1=p1+m;
s2=p2+m*m;
for(i=0;i<=9*k;i++)
for(j=i;j<=81*k;j++)
{
if(isPrime(i+s1)&&isPrime(j+s2))
ans+=f(k,i,j);
}
}
p1+=a[k];
p2+=a[k]*a[k];
}
for(i=0;i<=a[0];i++)
if(isPrime(p1+i)&&isPrime(i*i+p2)) ans++;
return ans;
} int lucky(int x,int y)
{
memset(dp,-1,sizeof(dp));
return com(y)-com(x-1);
}
转自 http://blog.csdn.net/shuyechengying/article/details/9164517
pongo英雄会-幸运数题解的更多相关文章
- [COJ0528]BJOI幸运数
[COJ0528]BJOI幸运数 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见"试题描述" 输出示例 见"试 ...
- Problem 1007 幸运数 线段树成段更新
题目链接: 题目 Problem 1007 幸运数 Time Limit: 2000 mSec Memory Limit : 131072 KB 问题描述 皮特的幸运数是2和5.只由幸运数字2和5组成 ...
- 蓝桥杯 历届试题 幸运数 dfs
历届试题 幸运数 时间限制:1.0s 内存限制:256.0MB 问题描述 幸运数是波兰数学家乌拉姆命名的.它采用与生成素数类似的"筛法"生成 . 首先从1开始写出自然数1,2, ...
- 京东2017校园招聘笔试题 【第K个幸运数】
题目描述 4和7是两个幸运数字,我们定义,十进制表示中,每一位只有4和7两个数的正整数都是幸运数字. 前几个幸运数字为:4,7,44,47,74,77,444,447... 现在输入一个数字K,输出第 ...
- [51NOD1230]幸运数(数位DP)
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1230 dp(l,s,ss)表示长度为l的数各位和为s,各位平方 ...
- C#版 - Leetcode 504. 七进制数 - 题解
C#版 - Leetcode 504. 七进制数 - 题解 Leetcode 504. Base 7 在线提交: https://leetcode.com/problems/base-7/ 题目描述 ...
- C#版 - Leetcode 306. 累加数 - 题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...
- C#版(打败97.89%的提交) - Leetcode 202. 快乐数 - 题解
版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - L ...
- Python 计算当真因子个数为偶数个时为幸运数,计算区间内幸运数之和
晚饭后朋友发来个问题,正好无事做,动手写了一下 若一个正整数有偶数个不同的真因子,则称该数为幸运数.如4含有2个真因子为 1 和 2 .故4是幸运数.求[2,100]之间的全部幸运数之和. 常规思路 ...
随机推荐
- 谈谈.NET,Java,php
开通博客后,一直都是转点别的朋友写的有意思的博文,今天我来写我在博客园的第一篇文章,说的不对的地方请你指正.希望本文能为一些准备学习编程的朋友有一点帮助. 开发桌面程序一直都是c语言,c++的天下,因 ...
- 从送外卖到建站售主机还有共享自行车说起-2017年8月江西IDC排行榜与发展报告
曾几何时,送外卖,这样的"低技术含量"工作,很难被互联网公司看上,直到百度将其当作连接终端用户与大数据的管道. 同样,销售主机域名和建站业务,本也是"微小体量" ...
- 使用Docker搭建简易的 Java Web 环境
 从[<从最简单的入手学习 Docker ...
- angularjs-1.3代码学习-$parse
这次我们来看一下angular的Sandboxing Angular Expressions.关于内置方法的,核心有两块:Lexer和Parser.其中大家对$parse可能更了解一点.好了不多废话, ...
- poj 3621 二分+spfa
题意:给出一个有向图,问求一个回路,使得回路上的点权之和/边权之和最大. 这题主要是分析出如何确定ans值.我们将(a1*x1+a2*x2+..+an*xn)/(b1*x1+b2*x2+..+bn*x ...
- 【集美大学1411_助教博客】团队作业9——测试与发布(Beta版本)
写在前面的话 已经看到了大家的发布成果,很欣喜,虽然有的团队的产品还是有一点问题,但大家也都发布成功了,这就是软件的魅力.但还是要说一些问题,大家录的视频不是没人讲解就是讲得太快,在我看来这都没有在卖 ...
- 【beta】阶段 第六次 Scrum Meeting
每日任务 1.本次会议为第六次 Meeting会议: 2.本次会议在周六上午大课间,在陆大楼召开,召开本次会议为15分钟. 一.今日站立式会议照片 二.每个人的工作 (有work item 的ID) ...
- 【Alpha】 第七次Daily Scrum Meeting
一.本次会议为第七次meeting会议 二.时间:9:37AM-9:50AM 地点:禹州三楼 三.会议站立式照片 四.今日任务 成员 昨日任务 今日任务 林清青 学习并了解微信程序相关方面知识,为小组 ...
- 201521123001《Java程序设计》第5周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 1.2 可选:使用常规方法总结其他上课内容. 答:关于接口: 1.接口是一种抽象,抽取出了共同行为: 2.能够更加清晰地把系统 ...
- 201521123030《Java程序设计》第4周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. 控制可见性的4个访问修饰符 private -- 仅对本类可见 public -- 对所有类 ...