poj 3373 Changing Digits
2017-01-12 14:13
399 查看
Changing Digits
Given two positive integers n and k, you are asked to generate a new integer, say m, by changing some (maybe none) digits of n, such that the following properties holds: m contains no leading zeros and has the same length as n (We consider zero itself a one-digit integer without leading zeros.) m is divisible by k among all numbers satisfying properties 1 and 2, m would be the one with least number of digits different from n among all numbers satisfying properties 1, 2 and 3, m would be the smallest one Input There are multiple test cases for the input. Each test case consists of two lines, which contains n(1≤n≤10100) and k(1≤k≤104, k≤n) for each line. Both n and k will not contain leading zeros. Output Output one line for each test case containing the desired number m. Sample Input 2 2 619103 3219 Sample Output 2 119103 Source POJ Monthly--2007.09.09, Rainer |
提示
题意:给出两个正整数n,k(1<=k<=10^4,1<=n<=10^100,k<=n),根据以下规则求出m:
1.n的位数和m相同。
2.m可以被k整除。次
3.优先考虑尽可能然n和m的每一位数相同。
4.在满足3个条件的情况下尽可能的使m的为最小。
之后输出m。
思路:
实际上对于任何一个n都有至少改变len(k)次就可得到答案。因为我们在n中改变len(k)次可以得到10^len(k)个数,其中最坏的情况就是把n的后len(k)位都给改了。(这里的len(k)为k的位数)
当k=10000时,我们可知把后四位全改为0即可,因此n可改变的位数最大为4,可做。还需要加上搜索标记,当前状态是否已经搜过。
刷题刷到现在应该没有对这题直接上double或long long的吧。。。
示例程序
Source Code Problem: 3373 Code Length: 1134B Memory: 20168K Time: 1157MS Language: GCC Result: Accepted #include <stdio.h> #include <string.h> char s[101],ans[101],ch[101]; //s[]为初始的n,ans[]为m,ch[]为搜索时中转的变量 int k,v[5][101][10000],len,step; //len为n的位数,step为最多改变的位数个数 void dfs(int change,int deep,int sum) //change为当前状态所改变的位数个数,deep为当前个数,sum为进行取模的过程 { int i; if(deep==len) { if(change<step&&sum==0) //我们对每一位数都是从小到大开始枚举的,要保证改变位数要小于之前的 { step=change; strcpy(ans,ch); } return; } if(change>=step) { return; } if(v[change][deep][sum]==1) { return; } v[change][deep][sum]=1; //当前状态记录,防止重复遍历 for(i=0;9>=i;i++) { ch[deep]='0'+i; if(ch[deep]!=s[deep]) { dfs(change+1,deep+1,(sum*10+i)%k); } else { dfs(change,deep+1,(sum*10+i)%k); } } } int main() { int i; while(scanf("%s",s)!=EOF) { scanf("%d",&k); len=strlen(s); strcpy(ch,s); step=5; memset(v,0,sizeof(v)); for(i=1;9>=i;i++) { ch[0]='0'+i; if(ch[0]!=s[0]) { dfs(1,1,i%k); } else { dfs(0,1,i%k); } } printf("%s\n",ans); } return 0; }
相关文章推荐
- poj 3373 Changing Digits(记忆化搜索)
- poj 3373 Changing Digits (DFS + 记忆化剪枝+鸽巢原理思想)
- POJ 3373 Changing Digits
- poj 3373 Changing Digits
- POJ 3373 Changing Digits
- POJ 3373 Changing Digits(DP)
- poj3373——Changing Digits
- poj 3373 Changing Digits
- poj 3373 Changing Digits
- POJ 3373 Changing Digits 好蛋疼的DP
- POJ-3373-Changing Digits
- POJ 3373 Changing Digits 好蛋疼的DP
- POJ 3373 Changing Digits(DP)
- 【poj 3373】Changing Digits 题意&题解&代码(C++)
- POJ 3373 Changing Digits
- poj3373--Changing Digits(DFS+剪枝///记忆化)
- poj 3373 Changing Digits(打表 + dfs + 剪枝 )
- POJ 3373 Changing Digits
- POJ 3373 Changing Digits(记录路径的dp)
- POJ 3373--Changing Digits