POJ3373Changing Digits

来源:互联网 发布:mac上能玩的热门网游 编辑:程序博客网 时间:2024/04/30 15:56
原文地址:POJ 3373 Changing Digits(记忆化搜索 dfs)作者:子任

【题意】

给出n和k,求一个数m,m是满足所有以下4个条件的数:(1)与n位数相同(2)能被k整除(3)与n相同位的数不相同最少(4)满足以上3个条件的最小值。其中1≤n≤10100 , 1≤k≤104,kn

【思路】

此题是看了别人的解题报告才写出来。一开始不知道怎么搜,没思路。我们知道:假设k的位数是D,那么改变n的最后D+1位,能得到k+1的顺序数,由鸽巣原理,这k+1个数中至少有1个数能被k整除。所以,至多替换n的D+1位,肯定能找到结果。(1)先搜比n小的数  (2)再搜比n的大的数 ,这样就能保证只要搜出结果来了,就一定是最小值。 (3)改变替换的个数 。直接这样搜,会TLE。进行剪枝,增加一数组remember[110][10010];remember[i][j]= c 表示 剩余替换次数为i,当前余数为j时,index 在区间[0,c-1]时都不成立。

【code】

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

char str[110];
int k, len;
int num[110], test[110];
int for_mod[110][10];

int remember[110][10010];

void init()
{
 int i, j;
 for(i = 0; i < 10; i++)
  for_mod[0][i] = i % k;
 for(i = 1; i < len; i++)
  for(j = 0; j <10; j++)
   for_mod[i][j]= (10 * for_mod[i-1][j]) % k;
 memset(remember,0,sizeof(remember[0])*len);
}

bool DFS(int left, int index, int mod)
{
 int i, j, tmp;
 if(mod == 0)
 {
  for(i = len-1; i>= 0; i--)
   printf("%d",test[i]);
  printf("n");
  return true;
 }
 if(remember[left][mod] > index ||left == 0)
  return false;
 for(i = index; i >= 0; i--)
 {
  for(j = 0; j <num[i]; j++)
  {
   if(i == len-1&& j == 0) //头不为0
    continue;
   tmp =for_mod[i][j] + mod - for_mod[i][num[i]];
   tmp %=k;
   if(tmp< 0)
    tmp+= k;
   test[i] =j;
   if(DFS(left-1,i-1,tmp))
    returntrue;
  }
  test[i] = num[i];
 }
 for(i = 0; i <= index; i++)
 {
  for(j = num[i]+1; j< 10; j++)
  {
   tmp =for_mod[i][j] + mod - for_mod[i][num[i]];
   tmp %=k;
   if(tmp< 0)
    tmp+= k;
   test[i] =j;
   if(DFS(left-1,i-1,tmp))
    returntrue;
  }
  test[i] = num[i];
 }
 remember[left][mod] = index + 1;
 return false;
}

int main()
{
 int i, mod;
 while(scanf("%s",str) != -1)
 {
  scanf("%d",&k);
  len = strlen(str);
  mod = 0;
  init();
  for(i = 0; i <len; i++)
  {
   num[i] =test[i] = str[len-i-1] - '0';
   mod +=for_mod[i][num[i]];
   mod %=k;
  }
  for(i = 0;;i++)
  {
   if(DFS(i,len-1,mod))
    break;
  }
 }
 return 0;
}

0 0
原创粉丝点击