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]之间的全部幸运数之和. 常规思路 ...
随机推荐
- spring mvc:注解@ModelAttribute妙用
在Spring mvc中,注解@ModelAttribute是一个非常常用的注解,其功能主要在两方面: 运用在参数上,会将客户端传递过来的参数按名称注入到指定对象中,并且会将这个对象自动加入Model ...
- 南昌招聘.net开发大牛
职位诱惑: 12年名企5险1金齐全+WEB&移动研发=丰厚回报 职位描述: 聘精通web开发成员共同成就事业! 中国领先的WEB内核 研发机构.华中地区唯一自主CMS研发厂商.江西最大的网站服 ...
- poj 1149经典网络流构图
题意:m个猪圈,n个客户,每个客户给出选则猪圈的钥匙和需要购买猪的个数,其中每次客户购买时客户选则的猪圈数量可以相互更换,问最大购买数量. 思路:以客户作为除源点汇点之外的点,然后对于每个猪圈从源点连 ...
- Excel表单的读取与处理 PHPExcel与Apache POI
近日,连续遇到需要对Excel表单内容进行读取的需求.一个是在php环境下,一个是在java环境下.这里简要记录这两种环境,利用第三方提供的函数库对Excel进行处理的方法. d0710 : Fini ...
- 转:【Java并发编程】之九:死锁(含代码)
转载请注明出处:http://blog.csdn.net/ns_code/article/details/17200937 当线程需要同时持有多个锁时,有可能产生死锁.考虑如下情形: 线程A当前持有互 ...
- 转:【Java集合源码剖析】LinkedHashmap源码剖析
转载请注明出处:http://blog.csdn.net/ns_code/article/details/37867985 前言:有网友建议分析下LinkedHashMap的源码,于是花了一晚上时 ...
- 【Alpha】 第七次Daily Scrum Meeting
一.本次会议为第七次meeting会议 二.时间:9:37AM-9:50AM 地点:禹州三楼 三.会议站立式照片 四.今日任务 成员 昨日任务 今日任务 林清青 学习并了解微信程序相关方面知识,为小组 ...
- 【Alpha】——Fifth Scrum Meeting
一.今日站立式会议照片 二.每个人的工作 成员 昨天已完成的工作 今天计划完成的工作 李永豪 测试统计功能 对统计出现的问题进一步完善 郑靖涛 着手编写报表设计 继续报表设计 杨海亮 协助编写统计功能 ...
- 201521123104 《Java程序设计》第6周学习总结
1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 2. 书面作业 1. clone方法 1.1 Object ...
- 201521123062《Java程序设计》第5周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 1.2 可选:使用常规方法总结其他上课内容. 2. 书面作业 1.代码阅读:Child压缩包内源代码 1.1 com.pare ...