poj 3373 Changing Digits
2013-07-18 09:01
621 查看
Description
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
Sample Output
View Code
此题属于记忆化深搜,再加点技巧。
题目大意:
给出2个整数n(n<10^100)和k(k<10000),求满足以下条件的整数m
1、m与n位数相同
2、m能被k整除
3、满足以上两点时,m和n在相同位置的地方,数字不同的个数最少
4、满足以上三点时,m值最小
bool DFS(int pos,int num,int m);
传参有3个:pos,num,m
pos:当前搜索区间为[0,pos]
num:在区间[0,pos]中剩余 允许改变的数字的个数,个数从1个到len(n)个枚举,保证搜索到解时,n与m在相同位置处不同数字的个数是最少的(条件3)。
m:当前数字串m对k求模的值,初始化为a。
(1)搜索时先搜索比n小的数字,此时为了搜索到的解m是最小的,应该从区间[0,pos]的第pos位开始向第0位搜索,因为在相同num情况下,把高位数字变小所得到的m值更小。
(2)当(1)无解时,搜索比n大的数字,此时为了搜索到的解m是最小的,应该从区间[0,pos]的第0位开始向第pos位搜索,因为在相同num情况下,把低位数字变大所得到的m值更小。
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
#include <iostream> #include <stdio.h> #include <string.h> #include <string> using namespace std; char str[101]; int num1[101],num2[101]; int flag[101][10005]; int k; int len; int getY(int num[]) { int j; int m=0; for(j=len-1;j>=0;j--) { m=(m*10+num[j])%k; } return m; } void init() { int i; for(i=0;i<len;i++) { num1[i] = num2[i] = str[len-1-i]-'0'; } memset(flag,0,sizeof(flag)); } bool dfs(int pos,int num,int m) { int i,j; if(m==0) { for(i=len-1;i>=0;i--)printf("%d",num1[i]); printf("\n"); return true; } if(pos<0 || num<=flag[pos][m] || num==0) { return false; } for(i=pos;i>=0;i--) { for(j=0;j<num2[i];j++) { if(i==len-1 && j==0) { continue;//±ÜÃâÇ°µ¼0; } num1[i]=j; int a=getY(num1); if(dfs(i-1,num-1,a)) { return true; } } num1[i]=num2[i]; } for(i=0;i<=pos;i++) { for(j=num2[i]+1;j<=9;j++) { if(j==0 && i==len-1) { continue; } num1[i]=j; int a=getY(num1); if(dfs(i-1,num-1,a)) { return true; } } num1[i]=num2[i]; } flag[pos][m]=num; return false; } void solve() { int i; int m=getY(num1); for(i=1;i<=5;i++) { if(dfs(len-1,i,m))return; } } int main() { while(~scanf("%s%d",str,&k)) { len = strlen(str); init(); solve(); } }
View Code
此题属于记忆化深搜,再加点技巧。
题目大意:
给出2个整数n(n<10^100)和k(k<10000),求满足以下条件的整数m
1、m与n位数相同
2、m能被k整除
3、满足以上两点时,m和n在相同位置的地方,数字不同的个数最少
4、满足以上三点时,m值最小
解题步骤: 一、解决条件1很简单; 二、判断能否被k整除,使用同余模公式,解决大数能否被整除问题; 三、尽可能改变少的数字来满足条件
bool DFS(int pos,int num,int m);
传参有3个:pos,num,m
pos:当前搜索区间为[0,pos]
num:在区间[0,pos]中剩余 允许改变的数字的个数,个数从1个到len(n)个枚举,保证搜索到解时,n与m在相同位置处不同数字的个数是最少的(条件3)。
m:当前数字串m对k求模的值,初始化为a。
(1)搜索时先搜索比n小的数字,此时为了搜索到的解m是最小的,应该从区间[0,pos]的第pos位开始向第0位搜索,因为在相同num情况下,把高位数字变小所得到的m值更小。
(2)当(1)无解时,搜索比n大的数字,此时为了搜索到的解m是最小的,应该从区间[0,pos]的第0位开始向第pos位搜索,因为在相同num情况下,把低位数字变大所得到的m值更小。
具体看代码。
相关文章推荐
- 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(记忆化搜索)
- poj 3373 Changing Digits
- poj 3373 Changing Digits
- POJ 3373--Changing Digits
- poj3373——Changing Digits
- POJ_3373_Changing Digits_DP
- POJ 3373 Changing Digits(记录路径的dp)
- poj 3373 Changing Digits
- POJ 3373 Changing Digits
- poj3373--Changing Digits(DFS+剪枝///记忆化)
- POJ 3373 Changing Digits(DP)
- POJ-3373-Changing Digits
- POJ 3373 Changing Digits
- poj 3373 Changing Digits(打表 + dfs + 剪枝 )
- POJ 3373 Changing Digits 记忆化搜索