SRM 403(1-250pt, 1-500pt)
DIV1 250pt
题意:称各个数位只含有4和7的数为lucky number,给定a,b,求[a, b]中的lucky number有多少个。a, b <= 10^9
解法:很明显的数位dp,写出来也就20行左右。本来以为最近刚好在做数位dp,可以很快出,结果我想着刚才做的那个数位dp,脑袋进水居然直接敲了段递归的代码还半天没调出来.......然后很快写了段非递归的代码过了.....160score...
后来看官方题解说,由于10^9内实际上只有1022个lucky number,所以可以求全部生成出来,看有哪些在[a, b]上。
tag:数位dp,think
1 // BEGIN CUT HERE 2 /* 3 * Author: plum rain 4 * score : 5 */ 6 /* 7 8 */ 9 // END CUT HERE 10 #line 11 "TheLuckyNumbers.cpp" 11 #include <sstream> 12 #include <stdexcept> 13 #include <functional> 14 #include <iomanip> 15 #include <numeric> 16 #include <fstream> 17 #include <cctype> 18 #include <iostream> 19 #include <cstdio> 20 #include <vector> 21 #include <cstring> 22 #include <cmath> 23 #include <algorithm> 24 #include <cstdlib> 25 #include <set> 26 #include <queue> 27 #include <bitset> 28 #include <list> 29 #include <string> 30 #include <utility> 31 #include <map> 32 #include <ctime> 33 #include <stack> 34 35 using namespace std; 36 37 #define CLR(x) memset(x, 0, sizeof(x)) 38 #define CLR1(x) memset(x, -1, sizeof(x)) 39 #define PB push_back 40 #define SZ(v) ((int)(v).size()) 41 #define ALL(t) t.begin(),t.end() 42 #define zero(x) (((x)>0?(x):-(x))<eps) 43 #define out(x) cout<<#x<<":"<<(x)<<endl 44 #define tst(a) cout<<#a<<endl 45 #define CINBEQUICKER std::ios::sync_with_stdio(false) 46 47 typedef vector<int> VI; 48 typedef vector<string> VS; 49 typedef vector<double> VD; 50 typedef pair<int, int> pii; 51 typedef long long int64; 52 53 const double eps = 1e-8; 54 const double PI = atan(1.0)*4; 55 const int maxint = 2139062143; 56 57 int dit[20], two[20]; 58 59 int gao(int x) 60 { 61 two[0] = 1; 62 for (int i = 1; i < 15; ++ i) 63 two[i] = two[i-1] * 2; 64 65 int len = 0; 66 while (x){ 67 dit[len++] = x % 10; 68 x /= 10; 69 } 70 71 int ret = 0; 72 for (int i = 1; i < len; ++ i) 73 ret += two[i]; 74 for (int i = len-1; i >= 0; -- i){ 75 if (4 < dit[i]) ret += two[i]; 76 if (7 < dit[i]) ret += two[i]; 77 if (dit[i] != 4 && dit[i] != 7) break; 78 } 79 return ret; 80 } 81 82 class TheLuckyNumbers 83 { 84 public: 85 int count(int a, int b){ 86 return gao(b+1) - gao(a); 87 } 88 89 // BEGIN CUT HERE 90 public: 91 void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); } 92 private: 93 template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); } 94 void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } } 95 void test_case_0() { int Arg0 = 1; int Arg1 = 1000000000; int Arg2 = 1022; verify_case(0, Arg2, count(Arg0, Arg1)); } 96 void test_case_1() { int Arg0 = 11; int Arg1 = 20; int Arg2 = 0; verify_case(1, Arg2, count(Arg0, Arg1)); } 97 void test_case_2() { int Arg0 = 74; int Arg1 = 77; int Arg2 = 2; verify_case(2, Arg2, count(Arg0, Arg1)); } 98 void test_case_3() { int Arg0 = 1000000; int Arg1 = 5000000; int Arg2 = 64; verify_case(3, Arg2, count(Arg0, Arg1)); } 99 100 // END CUT HERE 101 102 }; 103 104 // BEGIN CUT HERE 105 int main() 106 { 107 // freopen( "a.out" , "w" , stdout ); 108 TheLuckyNumbers ___test; 109 ___test.run_test(-1); 110 return 0; 111 } 112 // END CUT HERE
View Code
DIV1 500pt
题意:称各个数位只含有4和7的数为lucky number,称完全由来自vector<int> numbers(含有lucky number和也含有unlucky number)里面的lucky number组成,且每一个a[i]的末位数字和a[i+1]的首位数字均相同的序列为lucky sequence。给定vector<int> numbers和int n,求长度为n的lucky sequence有多少个。只要一个数不同,则lucky sequence视为不同。
解法:lucky number分为四种,分别为4开头4结尾的,4开头7结尾的,7开头4结尾的,7开头7结尾的。若a[i]属于第A类,且a[i+1]可以为B类,则从A向B连接一条有向边。这样,就相当于求长度为n的路径有多少条。
我最初的想法是二分,设f(x, s, e)表示求长度为x,从s类开始,从e类结束的路径有多少条,f(x, s, e)由 f(x/2, s, i) 和 f(x-x/2, i, e)求得。我以为这样二分以后时间复杂度降低了,实际上每次二分都有4个决策,时间复杂度反而提升了,于是我毫无悬念地TLE了。然后,我改了代码,把x / 2变成了x / 10000,即将x分为10001段来求,由于前面每一段长度均为x/10000,后面一段长度为x - x/10000,所以实际上只需要求20个东西,这样时间复杂度就降低到能接受的范围了。
虽然算是水过了这道题,还是蛮开心的.....
官方题解给出的方法是用矩阵快速幂优化。其实要构造这个并不难吧。。。当时想了一下用矩阵,怎么就没想出来呢。。。。
tag:矩阵乘法
1 // BEGIN CUT HERE 2 /* 3 * Author: plum rain 4 * score : 5 */ 6 /* 7 8 */ 9 // END CUT HERE 10 #line 11 "TheLuckySequence.cpp" 11 #include <sstream> 12 #include <stdexcept> 13 #include <functional> 14 #include <iomanip> 15 #include <numeric> 16 #include <fstream> 17 #include <cctype> 18 #include <iostream> 19 #include <cstdio> 20 #include <vector> 21 #include <cstring> 22 #include <cmath> 23 #include <algorithm> 24 #include <cstdlib> 25 #include <set> 26 #include <queue> 27 #include <bitset> 28 #include <list> 29 #include <string> 30 #include <utility> 31 #include <map> 32 #include <ctime> 33 #include <stack> 34 35 using namespace std; 36 37 #define CLR(x) memset(x, 0, sizeof(x)) 38 #define CLR1(x) memset(x, -1, sizeof(x)) 39 #define PB push_back 40 #define SZ(v) ((int)(v).size()) 41 #define ALL(t) t.begin(),t.end() 42 #define zero(x) (((x)>0?(x):-(x))<eps) 43 #define out(x) cout<<#x<<":"<<(x)<<endl 44 #define tst(a) cout<<#a<<endl 45 #define CINBEQUICKER std::ios::sync_with_stdio(false) 46 47 typedef vector<int> VI; 48 typedef vector<string> VS; 49 typedef vector<double> VD; 50 typedef pair<int, int> pii; 51 typedef long long int64; 52 53 const double eps = 1e-8; 54 const double PI = atan(1.0)*4; 55 const int maxint = 2139062143; 56 const int mod = 1234567891; 57 58 int64 cnt[4]; 59 pii temp[4]; 60 set<int> st; 61 int64 pat[4][4], d[40000][4][4]; 62 int64 an[40000][4]; 63 64 int gao(int x) 65 { 66 pii num; 67 num.second = x % 10; 68 while (x >= 10){ 69 int tmp = x % 10; 70 x /= 10; 71 if (tmp != 7 && tmp != 4) return -1; 72 } 73 num.first = x % 10; 74 for (int i = 0; i < 4; ++ i) 75 if (num == temp[i]) return i; 76 return -1; 77 } 78 79 int64 rec(int len, int s, int e) 80 { 81 if (!len) return s == e; 82 if (len == 1) return pat[s][e]; 83 84 if (len < 40000 && d[len][s][e] != -1) 85 return d[len][s][e]; 86 87 if (len < 40000){ 88 int haf = len / 2; 89 int64 &ret = d[len][s][e]; 90 ret = 0; 91 for (int i = 0; i < 4; ++ i) 92 ret = (ret + rec(haf, s, i) * rec(len-haf, i, e)) % mod; 93 return ret; 94 } 95 96 int haf = len / 40000; 97 CLR (an); 98 for (int i = 0; i < 4; ++ i) 99 an[0][i] = rec(haf, s, i); 100 for (int i = 1; i < 40000; ++ i) 101 for (int j = 0; j < 4; ++ j) 102 for (int k = 0; k < 4; ++ k) 103 an[i][j] = (an[i][j] + an[i-1][k] * rec(haf, k, j)) % mod; 104 int64 ret = 0; 105 for (int i = 0; i < 4; ++ i) 106 ret = (ret + an[39999][i] * rec(len-haf*40000, i, e)) % mod; 107 return ret; 108 } 109 110 class TheLuckySequence 111 { 112 public: 113 int count(vector <int> num, int len){ 114 temp[0] = make_pair(4,4); temp[1] = make_pair(4,7); 115 temp[2] = make_pair(7,4); temp[3] = make_pair(7,7); 116 117 CLR (cnt); st.clear(); 118 for (int i = 0; i < (int)num.size(); ++ i){ 119 int tmp = gao(num[i]); 120 if (tmp != -1 && !st.count(num[i])){ 121 ++ cnt[tmp]; 122 st.insert(num[i]); 123 } 124 } 125 CLR (pat); 126 for (int i = 0; i < 4; ++ i) 127 for (int j = 0; j < 4; ++ j) 128 if (temp[i].second == temp[j].first){ 129 pat[i][j] = cnt[i]; 130 } 131 132 CLR1 (d); 133 int64 ret = 0; 134 for (int i = 0; i < 4; ++ i) 135 for (int j = 0; j < 4; ++ j) 136 ret = (ret + rec(len-1, i, j) * cnt[j]) % mod; 137 return (int)ret; 138 } 139 140 // BEGIN CUT HERE 141 public: 142 void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); } 143 private: 144 template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); } 145 void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } } 146 void test_case_0() { int Arr0[] = {44, 47, 74, 77, 44, 47, 74, 77}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 1000000000; int Arg2 = 1133762585; verify_case(0, Arg2, count(Arg0, Arg1)); } 147 void test_case_1() { int Arr0[] = {47, 74, 47}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 3; int Arg2 = 2; verify_case(1, Arg2, count(Arg0, Arg1)); } 148 void test_case_2() { int Arr0[] = {100, 4774, 200, 747, 300}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 47; int Arg2 = 2; verify_case(2, Arg2, count(Arg0, Arg1)); } 149 void test_case_3() { int Arr0[] = {44, 47, 74, 77}; vector <int> Arg0(Arr0, Arr0 + (sizeof(Arr0) / sizeof(Arr0[0]))); int Arg1 = 2; int Arg2 = 8; verify_case(3, Arg2, count(Arg0, Arg1)); } 150 151 // END CUT HERE 152 153 }; 154 155 // BEGIN CUT HERE 156 int main() 157 { 158 // freopen( "a.out" , "w" , stdout ); 159 TheLuckySequence ___test; 160 ___test.run_test(-1); 161 return 0; 162 } 163 // END CUT HERE
View Code
转载于:https://www.cnblogs.com/plumrain/p/srm_403.html
SRM 403(1-250pt, 1-500pt)相关推荐
- SRM 533 DIV2
很长时间没做TC了,再说自己做的也确实相当少,所以不是很熟+思路来的比较慢所以做得不是多么好,只做出了250pt,500pt的思路对还没敲完就结束了.话说TC,CF什么的真的很锻炼人的思维能力可就是老 ...
- Topcoder Open 2011 Qualification Round 3报告
第一篇竞赛报告--TCO的前两场QR的情况不容乐观,所以把我逼得起早做TCO QR3.最终rank498,rate有微微上涨(不调到DIV2我就很高兴了~).总体情况问题在于熟练程度,最大的问题就是手 ...
- SRM 613 div1 500pt
Mobius 函数除草... (1)F(n) = sigma (G(d)) d | n G(n) = sigma (F(d) * miu (n / d)) d | n 还有另外一个表达形式 ...
- SRM 499 250pt
题意:就是给你一些数,这些数中其中有两个数是x+y的值和x-y的值,求使x*y的最大值. 思路:当两个数的和一定时,若要使x*y得值越大,则x和y越接近越好,即x-y得差越小越好.因此,我们可以先对元 ...
- SRM 400(1-250pt, 1-500pt)
DIV1 250pt 题意:给定一个正整数n(n <= 10^18),如果n = p^q,其中p为质数,q > 1,则返回vector<int> ans = {p, q},否则 ...
- SRM 440(1-250pt, 1-500pt)
DIV1 250pt 题意:小球从一段折线斜坡上滚下来,告诉所用时间,求重力加速度. 解法:二分答案模拟即可. tag:二分,simulation 1 // BEGIN CUT HERE 2 /* 3 ...
- SRM 542 DIV2
一道DIV2里面500pt的题目想了3天还是没有想出来,这是什么水平....太菜了,弱爆了,该怎么办呢?怎么样才能成为高手呢? 250pt: 题意:题意很简单,就是说兔子之间的合作问题,每对兔子间有个 ...
- SRM 567 div2
250pt.... 500pt 题意:给n和m,a,b满足(1 <= a <= n, 1 <= b <= m),SSR(a, b) = (sqrt(a) + sqrt(b))^ ...
- TC SRM 553 DIV2
转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526 by---cxlove 赤裸裸的又在送rate. 250 ...
- SRM 453.5(Div1)
这场的前两题异乎寻常的简单啊,怪不得是.5了呢 250pt: 大水题... 500pt: 算出来总的平面图构成的方案数不会太多,所以暴力背包吧,常数很小,放心跑吧... bool vis[100001 ...
最新文章
- 这12张手绘图,让我彻底搞懂了微服务架构!
- ^和$ emeditor
- 一条语句执行跨越若干个数据库
- lin总线可以控制几个节点_汽车上除了CAN通讯还有另外一种总线你需要知道
- VIM-配置-.vimrc
- ABAP Netweaver Authorization trace tool
- php pdo mysql 乱码,php pdo连接数据库 解决中文乱码问题(wordpress mysql 问号?? ??)...
- webservice之helloword(web)rs
- AngularJS scope 学习
- [转载] Python中Numpy包的用法
- 鸿蒙OS比fuchsia的优势,第一天带你走进华为开发者大会,了解鸿蒙OS
- HDU 1693 Eat the Trees ——插头DP
- 北京网信金服PHP薪资_【企航金服工资|企航金服待遇怎么样】-看准网
- 巧用CSS,愚人节极客式恶搞
- Python - 列表解析式( List_Comprehension)
- 【Codesys】-按钮启动外部.exe应用程序,按钮关闭HMI界面,桌面图标启动HMI界面。
- 难受难受,真它吗的难受... ...
- ABB机器人动作监控和无动作执行的使用
- RDKit | 基于RDKit和SMARTS的化学反应处理
- MySQL函数---条件判断函数
热门文章
- paip. uapi 过滤器的java php python 实现aop filter
- paip.提升用户体验----自定义移位操作符重载
- paip.提升开发效率之查询界面
- IP地址与子网掩码划分的心得
- (转)江南愤青丨丨监管办法之后,网贷一地鸡毛(2016年)
- (转)黄金交易革命即将到来?区块链技术让你像刷卡一样“刷黄金”
- Julia: 关于Github上的其它库
- 一个线上SQL死锁异常分析:深入了解事务和锁
- 非常有意思的35句话
- 【背包问题】基于matlab量子免疫克隆算法求解背包问题【含Matlab源码 424期】