SRM 510 2 250TheAlmostLuckyNumbersDivTwo(数位dp)
SRM 510 2 250TheAlmostLuckyNumbersDivTwo
Problem Statement
John and Brus believe that the digits 4 and 7 are lucky and all others are not. According to them, an almost lucky number is a number that contains at most one non-lucky digit in its decimal representation. Return the total number of almost lucky numbers between a and b, inclusive.
Definition
- ClassTheAlmostLuckyNumbersDivTwo
- Methodfind
- Parametersint , int
- Returnsint
- Method signatureint find(int a, int b)
Limits
- Time limit (s)2.000
- Memory limit (MB)64
Constraints
- a will be between 1 and 1,000,000, inclusive.
- b will be between a and 1,000,000, inclusive.
Test cases
- a4
- b7
Returns4
All numbers between 4 and 7 are almost lucky.- a8
- b19
Returns4
Numbers 8, 9, 14 and 17 are almost lucky.- a28
- b33
Returns0
No almost lucky numbers here.- a1234
- b4321
Returns36
This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <typeinfo>
#include <fstream> using namespace std;
int dp[][] , dp2[][];
int dig[] ;
int vis[] ; void init ()
{
memset (dp , , sizeof(dp)) ;
memset (dp2 , , sizeof(dp2) ) ;
for (int i = ; i < ; i ++) dp[][i] = ;
for (int i = ; i <= ; i ++ ) {
for (int j = ; j < ; j ++) {
dp[i][j] += dp[i-][] + dp[i-][] ;
}
}
int a , b , c = , d = ;
for (int i = ; i <= ; i ++) for (int j = ; j < ; j ++) dp2[i][j] = dp[i][j] ;
for (int i = ; i <= ; i ++) {
a = dp[i][] , b = dp[i][] ;
for (int j = ; j < ; j ++) {
if (!(j == || j == )) {
dp2[i][] += dp[i-][j] ;
dp2[i][] += dp[i-][j] ;
}
else if (j == ) {
dp2[i][] += c ;
dp2[i][] += c ;
}
else if (j == ) {
dp2[i][] += d ;
dp2[i][] += d ;
}
}
// printf ("dp[%d][4]=%d , dp[%d][7]=%d\n" , i , dp[i][4] , i , dp[i][7]) ;
c = dp2[i][] - a , d = dp2[i][] - b ;
}
} int cal (int x)
{
memset (dig , , sizeof(dig)) ;
memset (vis , , sizeof(vis)) ;
int ans = ;
int len = ;
int tmp = x ;
int cnt = ;
while (x) {
dig[len ++] = x % ;
x /= ;
}
for (int i = len - ; i >= ; i --) {
vis[i] = cnt ;
if (dig[i] != && dig[i] != ) cnt ++ ;
}
//for (int i = 0 ; i < dig[1] ; i ++) ans += dp[1][i] ;
// ans += 10 ;
// printf ("hahaha") ;
// printf ("%d " , vis[0]) ;
// for (int i = 1 ; i < len ; i ++) printf ("%d " , vis[i]) ; puts ("") ;
for (int i = ; i < len ; i ++) {
printf ("vis[%d]=%d:\n\n" , i , vis[i] ) ;
if (vis[i] == ) {
for (int j = ; j < dig[i] ; j ++) ans += dp2[i][j] ;
}
else if (vis[i] == ) {
for (int j = ; j < dig[i] ; j ++) if (j == || j == ) ans += dp[i][j] , printf ("dp[%d][%d]=%d\n" , i , j , dp[i][j]) ;
}
if (i == len - ) ans -= dp[i][] ;
}
printf ("ans = %d\n" , ans ) ;
if (len == ) {
ans += dp[][] ;
}
else {
ans += dp[][] ;
for (int i = ; i < len - ; i ++) {
for (int j = ; j < ; j ++) ans += dp2[i][j] ;
}
}
printf ("%d:ans = %d\n" , tmp , ans) ;
printf ("-----------------------------------\n") ;
return ans ;
} class TheAlmostLuckyNumbersDivTwo {
public:
int find(int a, int b) {
puts ("") ;
if (a > b) swap(a,b) ;
init () ;
printf ("%d ~ %d\n" , a , b) ;
// printf ("%d - %d\n" , cal(b) , cal(a-1)) ;
return cal(b+) - cal(a) ;
//return 0 ;
}
}; // CUT begin
ifstream data("TheAlmostLuckyNumbersDivTwo.sample"); string next_line() {
string s;
getline(data, s);
return s;
} template <typename T> void from_stream(T &t) {
stringstream ss(next_line());
ss >> t;
} void from_stream(string &s) {
s = next_line();
} template <typename T>
string to_string(T t) {
stringstream s;
s << t;
return s.str();
} string to_string(string t) {
return "\"" + t + "\"";
} bool do_test(int a, int b, int __expected) {
time_t startClock = clock();
TheAlmostLuckyNumbersDivTwo *instance = new TheAlmostLuckyNumbersDivTwo();
int __result = instance->find(a, b);
double elapsed = (double)(clock() - startClock) / CLOCKS_PER_SEC;
delete instance; if (__result == __expected) {
cout << "PASSED!" << " (" << elapsed << " seconds)" << endl;
return true;
}
else {
cout << "FAILED!" << " (" << elapsed << " seconds)" << endl;
cout << " Expected: " << to_string(__expected) << endl;
cout << " Received: " << to_string(__result) << endl;
return false;
}
} int run_test(bool mainProcess, const set<int> &case_set, const string command) {
int cases = , passed = ;
while (true) {
if (next_line().find("--") != )
break;
int a;
from_stream(a);
int b;
from_stream(b);
next_line();
int __answer;
from_stream(__answer); cases++;
if (case_set.size() > && case_set.find(cases - ) == case_set.end())
continue; cout << " Testcase #" << cases - << " ... ";
if ( do_test(a, b, __answer)) {
passed++;
}
}
if (mainProcess) {
cout << endl << "Passed : " << passed << "/" << cases << " cases" << endl;
int T = time(NULL) - ;
double PT = T / 60.0, TT = 75.0;
cout << "Time : " << T / << " minutes " << T % << " secs" << endl;
cout << "Score : " << * (0.3 + (0.7 * TT * TT) / (10.0 * PT * PT + TT * TT)) << " points" << endl;
}
return ;
} int main(int argc, char *argv[]) {
cout.setf(ios::fixed, ios::floatfield);
cout.precision();
set<int> cases;
bool mainProcess = true;
for (int i = ; i < argc; ++i) {
if ( string(argv[i]) == "-") {
mainProcess = false;
} else {
cases.insert(atoi(argv[i]));
}
}
if (mainProcess) {
cout << "TheAlmostLuckyNumbersDivTwo (250 Points)" << endl << endl;
}
return run_test(mainProcess, cases, argv[]);
}
// CUT end
数位dp,,,,蛮有趣的,写了我三天,还好现在是考试季。数位dp能大大减少复杂度,拿这道题来说。如果用暴力来做要O(1e6),但用数位dp来的话,只需O(70)!!!!!
但同时换来的是复杂的构造。
推荐:http://www.cnblogs.com/archimedes/p/numerical-digit-dp.html
SRM 510 2 250TheAlmostLuckyNumbersDivTwo(数位dp)的更多相关文章
- POJ 3689 Apocalypse Someday [数位DP]
Apocalypse Someday Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 1807 Accepted: 87 ...
- 【BZOJ1662】[Usaco2006 Nov]Round Numbers 圆环数 数位DP
[BZOJ1662][Usaco2006 Nov]Round Numbers 圆环数 Description 正如你所知,奶牛们没有手指以至于不能玩"石头剪刀布"来任意地决定例如谁 ...
- bzoj1026数位dp
基础的数位dp 但是ce了一发,(abs难道不是cmath里的吗?改成bits/stdc++.h就过了) #include <bits/stdc++.h> using namespace ...
- uva12063数位dp
辣鸡军训毁我青春!!! 因为在军训,导致很长时间都只能看书yy题目,而不能溜到机房鏼题 于是在猫大的帮助下我发现这道习题是数位dp 然后想起之前讲dp的时候一直在补作业所以没怎么写,然后就试了试 果然 ...
- HDU2089 不要62[数位DP]
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 数位DP GYM 100827 E Hill Number
题目链接 题意:判断小于n的数字中,数位从高到低成上升再下降的趋势的数字的个数 分析:简单的数位DP,保存前一位的数字,注意临界点的处理,都是套路. #include <bits/stdc++. ...
- 数位dp总结
由简单到稍微难点. 从网上搜了10到数位dp的题目,有几道还是很难想到的,前几道基本都是模板题,供入门用. 点开即可看题解. hdu3555 Bomb hdu3652 B-number hdu2089 ...
- 数位DP入门
HDU 2089 不要62 DESC: 问l, r范围内的没有4和相邻62的数有多少个. #include <stdio.h> #include <string.h> #inc ...
- 数位DP之奥义
恩是的没错数位DP的奥义就是一个简练的dfs模板 int dfs(int position, int condition, bool boundary) { ) return (condition ? ...
随机推荐
- 深入分析ConcurrentHashMap
术语定义 哈希算法 hash algorithm 是一种将任意内容的输入转换成相同长度输出的加密方式,其输出被称为哈希值. 哈希表 hash table 根据设定的哈希函数H(key)和处理冲突方 ...
- POJ 3678 Katu Puzzle(强连通 法)
题目链接 题意:给出a, b, c 和操作类型 (与或异或),问是否满足所有的式子 主要是建图: 对于 and , c == 1: 说明 a 和 b都是1,那么 0 就不能取, a' -> a ...
- Django admin美化插件suit
Django Suit 效果 使用前django页面 使用后django页面 安装 官方文档 http://django-suit.readthedocs.io/en/develop/index.ht ...
- css015 定位网页上的元素
css015 定位网页上的元素 一. 定位属性的功能 1. 四中类型的定位 Position: absolute relative fixed static a. 绝对定位 绝对定 ...
- MVC Autofac构造函数注入
建立 空的 MVC4项目 首先引用 NuGet 里 autofac 和 autofac .integration. mvc 然后 建立Model public class Person { publi ...
- IO多路复用及ThreadingTCPServer源码阅读
IO多路复用 socket模块是阻塞的,通过socket建立的服务端可以接收多个请求,但只能同时处理一个请求,其他请求都被阻塞.可以通过IO多路复用解决这个问题,socketserver内部使用的就是 ...
- 20145212 实验五《Java网络编程》
20145212 实验五<Java网络编程> 一.实验内容 1.运行下载的TCP代码,结对进行,一人服务器,一人客户端: 2.利用加解密代码包,编译运行代码,一人加密,一人解密: 3.集成 ...
- ListView 里面嵌套 GridView 遇到的问题及其解决方法。
我们直接入主题.所有问题例子请参照下图 1,怎样使图片具有点击事件? 答: 解决方法: 在你的BaseAdapter里面不要设置下面这三个东西,然后再设置GridView的onItemClick. g ...
- Unixbench测试工具和使用
安装过程 wget http://soft.laozuo.org/scripts/UnixBench5.1.3.tgz tar xf UnixBench5.1.3.tgz cd UnixBench5. ...
- 设计模式学习——观察者模式(Observer Pattern)
0. 前言 观察者模式在许多地方都能够用到,特别是作为MVC模式的一部分,在MVC中,模型(M):存放数据,视图(V):显示数据.当模型中的数据发生改变时,视图会得到通知,这是典型的观察者模式. 1. ...