problem1 link

令$f(x)$表示[0,x]中答案的个数。那么题目的答案为$f(b)-f(a-1)$

对于$f(x)$来说,假设$x$有$d$位数字,即$[0,d-1]$,那么可以进行动态规划,令$dp(i,s)$表示已经考虑了$[i,d-1]$位的数字,状态为$s$的方案数。状态需要五种:

0: 前面都是0

1: 前面不都是0,前高位数字小于$x$且未出现非4,7的数字

2: 前面不都是0,前高位数字等于$x$且未出现非4,7的数字
3: 前面不都是0,前高位数字小于$x$且出现非4,7的数字
4: 前面不都是0,前高位数字等于$x$且出现非4,7的数字

problem2 link

首先,只包含4和7的数字并不多。即便$a=1,b=10^{10}$,这中间的只包含的4,7的数字也只有$2^{1}+2^{2}+...+2^{10}$个。

假设预计算出这些数字存储在数组$A$中

那么从贪心的角度看,Join枚举的区间的开始一定是$A_{i}-bLen+1$,而 Brus枚举的区间一定是从$A_{j}+1$开始。

problem3 link

设$n$的$B$进制表示为$n=\sum_{i=0}^{K}a_{i}B^{i},a_{i}<B$

首先,当$K$较大时$B$会很小。因此可以分为三类分别计算:

(1) $K=1$。即$n=a*B+b$。枚举$a,b$,判断$B$是否存在即可。

(2) $K=2$。即$n=a*B^{2}+b*B+c$。枚举$a,b,c$然后判断是否存在$B$。这里可以进行的一个优化是:假设枚举了$a,b$,那么对于连续枚举的两个c,比如$c_{1},c_{2},c_{1}<c_{2}$来说,假如$a*B_{1}^{2}+b*B_{1}+c_{1}=n,a*B_{2}^{2}+b*B_{2}+c_{2}=n$,那么$B_{1}>B_{2}$。所以如果$a*B_{1}^{2}+b*B_{1}+c_{2}<n $,那么对于$(a,b,c_{2})$来说,必然没有对应的$B$的解

(3) $K \ge 3$。直接枚举$B$,判断得到的$a_{i}$是否都是lucky-number即可。

(这一道python跑不过,用了Java)

code for problem1

class TheAlmostLuckyNumbersDivOne:

    def find(self, a, b):
return self.calculate(b) - self.calculate(a - 1) def calculate(self, a):
print a
if a == 0:
return 1
d = []
while a != 0:
d.append(a % 10)
a /= 10
n = len(d)
f = self.newArray2D(n, 5, 0)
for i in range(d[n - 1] + 1):
if i == 0:
f[n - 1][0] += 1
elif i == d[n - 1]:
if i == 4 or i == 7:
f[n - 1][2] += 1
else:
f[n - 1][4] += 1
else:
if i == 4 or i == 7:
f[n - 1][1] += 1
else:
f[n - 1][3] += 1 for i in range(n - 2, -1, -1):
t = d[i]
for j in range(10):
if j == 0:
f[i][0] += f[i + 1][0]
f[i][3] += f[i + 1][1]
if j == t:
f[i][4] += f[i + 1][2]
elif j < t:
f[i][3] += f[i + 1][2]
elif j == 4 or j == 7:
f[i][1] += f[i + 1][0]
f[i][1] += f[i + 1][1]
if j == t:
f[i][2] += f[i + 1][2]
f[i][4] += f[i + 1][4]
elif j < t:
f[i][1] += f[i + 1][2]
f[i][3] += f[i + 1][4]
f[i][3] += f[i + 1][3] else:
f[i][3] += f[i + 1][0]
f[i][3] += f[i + 1][1]
if j == t:
f[i][4] += f[i + 1][2]
elif j < t:
f[i][3] += f[i + 1][2] return f[0][0] + f[0][1] + f[0][2] + f[0][3] + f[0][4] def newArray2D(self, n, m, init):
f = [0] * n
for i in range(n):
f[i] = [init] * m
return f

  

code for problem2

class TheLuckyGameDivOne:

    f = []
fLen = 0
a = 0
b = 0
jLen = 0
bLen = 0
cache = [] def generateLuckyNumber(self, x):
if x > self.b:
return
if x >= self.a:
self.f.append(x)
self.generateLuckyNumber(x * 10 + 4)
self.generateLuckyNumber(x * 10 + 7) def binarySearch(self, key):
if self.f[0] > key:
return 0
if self.f[self.fLen - 1] <= key:
return self.fLen
low = 0
high = self.fLen - 1
maxIndex = 0
while low <= high:
mid = (low + high) >> 1
if self.f[mid] <= key:
maxIndex = max(maxIndex, mid)
low = mid + 1
else:
high = mid - 1
return maxIndex + 1 def calculate(self, start, end):
result = self.binarySearch(start + self.bLen - 1) - self.binarySearch(start - 1)
for i in range(self.fLen):
bStart = self.f[i] + 1
bEnd = bStart + self.bLen - 1
if start <= bStart and bEnd <= end:
result = min(result, self.cache[i])
return result def init(self):
self.cache = [0] * self.fLen for i in range(self.fLen):
bStart = self.f[i] + 1
bEnd = bStart + self.bLen - 1
self.cache[i] = self.binarySearch(bEnd) - self.binarySearch(bStart - 1) def find(self, a, b, jLen, bLen):
self.a = a
self.b = b
self.jLen = jLen
self.bLen = bLen
self.generateLuckyNumber(0) self.f.sort()
if len(self.f) == 0:
return 0 self.fLen = len(self.f)
self.init() result = 0
for i in range(self.fLen + 1):
start = a
if i < self.fLen:
start = self.f[i] - bLen + 1
end = start + jLen - 1
if a <= start and end <= b:
result = max(result, self.calculate(start, end))
return result

  

code for problem3

import java.util.*;
import java.math.*;
import static java.lang.Math.*; public class TheLuckyBasesDivOne { List<Long> f = new ArrayList<>();
long n; void generateLuckyNumber(Long x) {
if (x > n) {
return;
}
if (x > 0) {
f.add(x);
}
generateLuckyNumber(x * 10 + 4);
generateLuckyNumber(x * 10 + 7);
} static boolean isLucky(Long x) {
if (x == 0) {
return false;
}
while (x > 0) {
if (x % 10 != 4 && x % 10 != 7) {
return false;
}
x /= 10;
}
return true;
} long calculate4() {
long result = 0;
for (long base = 2;;++ base) {
int num = 0;
boolean tag = true;
long x = n;
while (x > 0) {
tag = tag && isLucky(x % base);
num += 1;
x /= base;
}
if (num <= 3) {
break;
}
if (tag) {
result += 1;
}
}
return result;
} long searchMax(long a, long b, long c) {
long low = 0;
long high = (long)Math.sqrt(n) + 1;
long result = 0;
while (low <= high) {
long mid = (low + high) >> 1;
if (a <= n / mid && a * mid <= n / mid && b <= n / mid
&& a * mid * mid + b * mid + c <= n) {
result = Math.max(result, mid);
low = mid + 1;
}
else {
high = mid - 1;
}
}
return result;
} long calculate3() {
long result = 0;
for (long a : f) {
long B0 = a + 1;
if (a > n / B0 || a * B0 > n / B0) {
break;
}
for (long b : f) {
long B1 = Math.max(B0, b + 1);
if (a > n / B1 || a * B1 > n / B1
|| b * B1 > n || a * B1 * B1 + b * B1 > n) {
break;
}
long pre = -1;
for (long c : f) {
long B2 = Math.max(B1, c + 1);
if (a > n / B2 || a * B2 > n / B2
|| b * B2 > n || a * B2 * B2 + b * B2 + c > n) {
break;
}
if (pre != -1 && a * pre * pre + b * pre + c < n) {
continue;
}
pre = searchMax(a, b, c);
if (a * pre * pre + b * pre + c == n) {
result += 1;
}
}
}
}
return result;
} long calculate2() {
long result = 0;
for (long a : f) {
if (a * (a + 1) > n) {
break;
}
for (long b : f) {
long B = Math.max(a, b) + 1;
if (a > n / B || a * B + b > n) {
break;
}
long t = n - b;
if (t % a == 0 && t / a > a && t / a > b) {
result += 1;
}
}
}
return result;
}
public long find(long n) {
if (isLucky(n)) {
return -1;
} this.n = n;
generateLuckyNumber(0L);
Collections.sort(f); return calculate2() + calculate3() + calculate4();
}
}

  

topcoder srm 510 div1的更多相关文章

  1. Topcoder SRM 643 Div1 250<peter_pan>

    Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...

  2. Topcoder Srm 726 Div1 Hard

    Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...

  3. topcoder srm 714 div1

    problem1 link 倒着想.每次添加一个右括号再添加一个左括号,直到还原.那么每次的右括号的选择范围为当前左括号后面的右括号减去后面已经使用的右括号. problem2 link 令$h(x) ...

  4. topcoder srm 738 div1 FindThePerfectTriangle(枚举)

    Problem Statement      You are given the ints perimeter and area. Your task is to find a triangle wi ...

  5. Topcoder SRM 602 div1题解

    打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...

  6. Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串

    Problem Statement      The Happy Letter game is played as follows: At the beginning, several players ...

  7. Topcoder SRM 584 DIV1 600

    思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...

  8. TopCoder SRM 605 DIV1

    604的题解还没有写出来呢.先上605的. 代码去practice房间找. 说思路. A: 贪心,对于每个类型的正值求和,如果没有正值就取最大值,按着求出的值排序,枚举选多少个类型. B: 很明显是d ...

  9. topcoder srm 575 div1

    problem1 link 如果$k$是先手必胜那么$f(k)=1$否则$f(k)=0$ 通过对前面小的数字的计算可以发现:(1)$f(2k+1)=0$,(2)$f(2^{2k+1})=0$,(3)其 ...

随机推荐

  1. sqlmap常用技巧整理

    言 通过在乌云网上出现的很多SQL注入漏洞,因此来总结一下,大致使用SQLMAP所遇到的参数. 基本结构 基本SQLMAP的使用方式就如下所示,使用参数式的方式,按需求添加. 12 sqlmap.py ...

  2. LeetCode13.罗马数字转整数

    罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为两个并 ...

  3. case when 遇到varchar转为int类型值失败的错误

    问题描述: 在Sql Server 2005下, 使用如下语句报错:在将 varchar 值 '大' 转换成数据类型 int 时失败. 注:status 是整型字段 select ff=  case ...

  4. Web Audio初步介绍和实践

    Web Audio还是一个比较新的JavaScript API,它和HTML5中的<audio>是不同的,简单来说,<audio>标签是为了能在网页中嵌入音频文件,和播放器一样 ...

  5. oracle查询数据字典的sql

    使用的sql语句如下: select t1.username 用户, t2.TABLE_NAME 表名称, t3.comments 表业务含义, t2.COLUMN_NAME 字段名称, t4.com ...

  6. arcgis api for js简要笔记

    1.主要借助官网的接口文档和samplecode来学习 https://developers.arcgis.com/javascript/latest/api-reference/index.html ...

  7. callback源码分析——callbacks

    uvm的callback必须是提供者有预见性的留一些方法在function前后,这样在使用的时候,进行遍历调度即可 设计者,需要从uvm_callback定义一个基类,只定义function原型,定义 ...

  8. c++ 常用的数据结构

    set // constructing sets #include <iostream> #include <set> void checkin(std::set<int ...

  9. Python全栈-数据库介绍与基本操作

    .数据库管理软件的由来 数据库的产生是为了解决数据的永久储存.数据安全.以及对方对外服务时能够实现并发服务等效果.例如解决前面所学的Scoket编程中,在不考虑硬件问题的基础上,服务端服务多个客户端时 ...

  10. html5-css动画-2d

    div{    width: 300px;    height: 100px;    margin: 50px;    padding: 50px;    background: green;     ...