dp处理大数整除6的最大位数Divide by Six
2017-04-10 17:18
260 查看
题址:https://oj.ejq.me/problem/24
Divide by Six
Input file: standard inputOutput file: standard output Time limit: 1 secondMemory limit: 512 mebibytes
A positive integer number n is written on a blackboard. It consists of not more than 10^5105 digits.
You have to transform it into a mogicalnumber by erasing some of the digits, and you want to erase as few digits as possible.
The number is lucky if it consists of at least one digit, doesn't have leading zeroes and is a multiple of 6. For example, 0, 66,66666 are lucky numbers, and 00, 25, 77 are not.
Write a program which for the given nn will
find a mogical number such that nn can
be transformed into this number by erasing as few digits as possible. You can erase an arbitraty set of digits. For example, they don't have to go one after another in the number nn.
Print the length of your answer after the erasing.
If it's impossible to obtain a lucky number, print
The first line of input contains nn --
a positive integer ( 1\le
n \le 10^{100000}1≤n≤10100000 ).
Print one number — the number of your lucky number obtained by erasing as few as possible digits. If there is no answer, print
题意:一个小于等于100000位的数字n,(10^100000>=n>=1);在这个数字中选出一些数字(不可改变顺序)组成6的倍数,输出符合条件的最长的位数。
例如样例0010456,选1056符合条件。如果找不到符合条件的则输出-1s;
(下面出现的余数都表示取余6的余数)
思路:首先int dp[100010][6];dp【i】【j】表示前i位(余数为j)的最长的位数;
dp初始化为-1e9;用ans来存最大值,ans初始化也为-1e9。如果数字中有0的话,ans至少是1;
dp【i】【0】一定表示前i位能整除6的最大位数。
因为dp【i】【j】可以由dp【i-1】【k】+1得来。
下面的t表示第i位上的数字。
状态转移方程:dp[i][(j*10+t)%6]=max(dp[i][(j*10+t)%6],dp[i-1][j]+1);
附上AC代码:
杭电的一道类似题:http://acm.hdu.edu.cn/showproblem.php?pid=6020 都是好题。
Divide by Six
Input file: standard inputOutput file: standard output Time limit: 1 secondMemory limit: 512 mebibytes
A positive integer number n is written on a blackboard. It consists of not more than 10^5105 digits.
You have to transform it into a mogicalnumber by erasing some of the digits, and you want to erase as few digits as possible.
The number is lucky if it consists of at least one digit, doesn't have leading zeroes and is a multiple of 6. For example, 0, 66,66666 are lucky numbers, and 00, 25, 77 are not.
Write a program which for the given nn will
find a mogical number such that nn can
be transformed into this number by erasing as few digits as possible. You can erase an arbitraty set of digits. For example, they don't have to go one after another in the number nn.
Print the length of your answer after the erasing.
If it's impossible to obtain a lucky number, print
-1s.
Input
The first line of input contains nn --a positive integer ( 1\le
n \le 10^{100000}1≤n≤10100000 ).
Output
Print one number — the number of your lucky number obtained by erasing as few as possible digits. If there is no answer, print -1s.
Example
Input 1
0010456
Output 1
4
Input 2
11
Output 2
-1s
题意:一个小于等于100000位的数字n,(10^100000>=n>=1);在这个数字中选出一些数字(不可改变顺序)组成6的倍数,输出符合条件的最长的位数。
例如样例0010456,选1056符合条件。如果找不到符合条件的则输出-1s;
(下面出现的余数都表示取余6的余数)
思路:首先int dp[100010][6];dp【i】【j】表示前i位(余数为j)的最长的位数;
dp初始化为-1e9;用ans来存最大值,ans初始化也为-1e9。如果数字中有0的话,ans至少是1;
dp【i】【0】一定表示前i位能整除6的最大位数。
因为dp【i】【j】可以由dp【i-1】【k】+1得来。
下面的t表示第i位上的数字。
状态转移方程:dp[i][(j*10+t)%6]=max(dp[i][(j*10+t)%6],dp[i-1][j]+1);
附上AC代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #include<string> #define LL long long int #define inf 0x3f3f3f3f #define N 1000010 using namespace std; char a[100005]; int dp[100005][7]; int main() { while(~scanf("%s",a+1)) { int n=strlen(a+1); for(int i=0;i<=n;i++) for(int j=0;j<6;j++) dp[i][j]=-inf; int ans=-inf; for(int i=1;i<=n;i++) if(a[i]=='0') { ans=1; break; } for(int i=1;i<=n;i++) { int t=a[i]-'0'; if(t!=0) dp[i][t%6]=max(dp[i][t%6],1); for(int j=0;j<6;j++) dp[i][j]=max(dp[i-1][j],dp[i][j]); for(int j=0;j<6;j++) { dp[i][(j*10+t)%6]=max(dp[i][(j*10+t)%6],dp[i-1][j]+1); } ans=max(ans,dp[i][0]); } if(ans>0) printf("%d\n",ans); else printf("-1s\n"); } }比赛后看第一名的代码,才知道原来这题能用dp做。这真是一道好题啊啊啊。
杭电的一道类似题:http://acm.hdu.edu.cn/showproblem.php?pid=6020 都是好题。
相关文章推荐
- woj Divide by Six 数位dp
- 打印从1到最大的n位数(考虑大数问题)
- 事件处理原理(IOS篇) by sixleaves
- Divide by Six
- 动态规划:HDU1864-最大报销额(处理带小数的dp问题)
- 打印1到最大的n位数:大数问题,全排列实现
- poj 3181 把n 划分成 不大于m的若干数字 最大的划分方法 (dp +大数)
- 剑指第17题:打印从1到最大的n位数——大数问题
- 17年武汉大学网络赛—Divide by Six
- 2017 Wuhan University Programming Contest (Online Round) C. Divide by Six 分析+模拟
- 剑指17_打印从1到最大的n位数(大数问题)
- 剑指offer_面试题12_打印1到最大的n位数(大数问题)
- NBUT1461 数字整除(大数处理,减法、除法)
- 学弟问题两个(DP和大数问题处理)
- woj-Divide by Six
- 【编程题目】打印1到最大的n位数——关于大数问题的探讨(C++实现)
- CodeForces 507D The Maths Lecture 构造恰好n位数且存在一个后缀能被k整除的方法数 dp
- noip2009 细胞分裂 (质因数分解,处理大数间能否整除)
- 面试题12:打印1到最大的n位数(大数问题)
- 大数操作,用顺序表实现最大一百位数的加减法实现