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 ? ...
随机推荐
- Python 循环判断和数据类型
循环和判断 1.if 形式 if condition_1: statement_block_1 elif condition_2: statement_block_2 else: statement_ ...
- Build to win!——获得小黄衫的感想
UPDATE: 应栋哥要求,上传了无遮挡的正面照(我的内心其实是拒绝的!(ㄒoㄒ)) 一.前言&背景 从大一上C++课程开始,栋哥就开始安利他大三的软工实践课. 时间过得飞快,大学转眼就过去一 ...
- sql自带函数语句
--取数值表达式的绝对值select abs(-41) 41select abs(41) 41select abs(-41.12) 41.12select abs(41.12 ...
- 分页进阶--ajax+jquery+struts2
按照上次的分页逻辑,分页查询的业务大概需要几个“零件”:1.当前页:2.总页数:3.跳转页.后端需要处理的是:按照传送过来请求的页码返回相应地数据,并且接受初始化参数的请求:总页码.第一页的数据. 使 ...
- re正则表达式5_*
*表示匹配[0,正无穷大]次 * means math zero or more-----occur any number of times in the text. # -*- coding: ut ...
- Java——URL和URLConnection
使用URL读取内容 import java.awt.im.InputContext; import java.io.InputStream; import java.net.MalformedURLE ...
- 使用node的插件UglifyJs来合并和压缩文件
code: var fs = require('fs'); var jsp = require("./UglifyJS-master/uglify-js").parser; var ...
- xcode
1: info.plist IOS之Info.plist文件简介 http://www.apkbus.com/android-130240-1-1.html 在Xcode项目中读取plist文件 ht ...
- DESCryptoServiceProvider
public static byte[] DESEncrypt(byte[] data, byte[] sKey) { return DESEncrypt(data, sKey, sKey); } / ...
- ssh远程连接ubuntu
1. 首先在服务器上安装ssh的服务器端. $ sudo aptitude install openssh-server 2. 启动ssh-server. $ sudo /etc/init.d/ss ...