poj1426



poj1426

题意:输入一个正整数n,求出大于等于这个数的一个整数m(m只能由1和0组成),使得m能被n整除。要求1<=n<=200, m最多只能为100位数。


方法:同除模定理 + 深度优先 + 剪枝

由于m可以达到100位,所以它是一个大数,如果要用大数的方法处理则会比较麻烦而且速度慢。按照题目要求我们只是求出使得余数为0的m就行了,这里用到同余模定理:

(a*b)%m = (a%m*b%m)%m

(a + b)%m = (a%m + b%m)%m

例如111对7求余==(11*10 + 1)%7 = ((11%7*10%7 )%7 + 1%7)%7,假设我们每次增加一个0或1则能求出个位数加0或加1后的余数,写出函数:

    

int get_mod(int mod, int pre_resu , int m)
{
    return ((pre_resu * (10 % mod)) % mod + m % mod) % mod;
}

接下来是深度优先遍历和剪枝:

1.     当遍历超过100个数的时候返回-1,余数标记置为0,说明这条路不能在100以内得到结果,但该余数并不是得到到结果所以标记设为0,可以走该余数的路

2.     当遍历到已得到的余数时返回0,因为下一个余数是通过当前余数得到的,如果相同,则后续结果相同

3.     当得到余数为0时,结束遍历,返回1,输出结果

4.     其他情况则分别往个位加0和1


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1000

int flag[MAX] = {0};
char s[MAX] = {"\0"};

int get_mod(int mod, int pre_resu , int m)
{
    return ((pre_resu * (10 % mod)) % mod + m % mod) % mod;
}


int dfs(int mod, int pre_mod, int m, int index)
{  
     int cur_mod, resu = 0;
     cur_mod = get_mod(mod, pre_mod, m);
     
     if(index > 99)
     {
         return -1;
     }
     
     
	// printf("%s\n", s);
     if(flag[cur_mod] != 0)
     {
        // s[index] = '\0';
         return 0;
     }
       
     s[index] = m + '0';


     flag[cur_mod] = 1;
     
     if(cur_mod == 0){
         return 1;
     } 
     
     
     resu = dfs(mod, cur_mod, 0, index + 1);
     if(resu == 1)
     {
         return 1;
     }
     else
     {
		 s[index + 1] = '\0';
         if(resu == -1)
         {
             flag[cur_mod] = 0;
         }
         resu = dfs(mod, cur_mod, 1, index + 1);
         if(resu == 1)
         {
             return 1;
         }
         else if(resu == -1)
         {
			 s[index + 1] = '\0';
             flag[cur_mod] = 0;
             return -1;
         }
         else{
			 s[index + 1] = '\0';
             return 0;
     
		 }
		 
	 }
     
     
}



int main()
{
    freopen("input.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    int k, n = 0;
    
    while(++n < 201)//scanf("%d", &n) && n)
    {
     
        memset(flag, 0, sizeof(int) * MAX);
        memset(s, '\0', sizeof(char) * MAX); 
        k = dfs(n, 0, 1, 0);
        printf("%s\n", s);
    }
    
    system("pause");
    return 0;
}


以下是n=6时的余数情况:

1->4->4return0

  ->5->2->2return0

             ->3->0return1




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值