搜索+剪枝.求最小m%k==0(m会爆long long)

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

题意:
0算一个不含前导0的数
输入整数n,k,这两个数不含前导0
通过改变n每位上的数字但不改变n的长度从而产生一个数m,使得m满足以下4个条件
1.m与n位数相同
2.m%k==0
3.满足1.2的条件后,得到m尽量少的改动每位上的数字
4.满足1.2.3的条件后,求得的m尽量最小
注意:如果改动1位的m1和改动2位的m2,m1>m2,结果输出的是m1.y因为必须先要满足3,再考虑满足4

分析:
转载出处:http://exp-blog.com
思路:(搜索)
改变位数依次增加(优)&&从小到大搜索(次),一旦搜到,即是索要答案
注意
当m<n时,n先从高位->低位进行改变
当m>n时,n先从低位->高位进行改变

大佬的解析:
res=(m-(mod[i][num[i]]-mod[i][j])+k)%k;;
以数字 5234,k=27 为例,在本算法中数组m实际存放为数字的倒序4325,首位为第0位的“4”,同样 mod[][] 存放的是倒序数据。
数据存放: num[]=4325, k=27
已知 m=5234%27=23,现在要把ans的第3位的“5”修改为更小的“1”,已有 num[3]=5,设 j=1,即令num[3]=j,显然改变后实际的变化值为5000-1000=4000
我们现在要求的是m改变后的 1234%27 的值,而 1234%25=(5234%27 – 4000%27)%27。由于 5234%27=m=23 已知,那么只需求 4000%27。
而 4000%27=(5000%27-1000%27)%27,显然 5000%27 和 1000%27 已经保存在 mod[][] 中。 5000%27=mod[3][num[3] ] ,1000%27=mod[3][ j ],说到这里应该都了解了。

关于剪枝:
定义二维数组 int** f
令 f[pos][m]=cnt;
当搜索m的位置区间为 [0,pos],且当前数字串m对k取模值为 m时,
若剩下允许的修改数字的个数只允许修改cnt个,
则无论如何修改区间 [0,pos] 内的数字也无法使得 m==0 ,
那么对于同样的pos和 m, 小于cnt的个数则更加不可能了

#include<stdio.h>
#include<string.h>
#define N 110
#define NN 10010
char str[N];
int mod[N][10];//mod[][]能组合出任意len(n)位内的整数对k求模后的值 
int ans[N];//倒存n,它会发生改变 
int num[N];//倒存n,不会变,为了还原以前被改变的 
int f[N][NN];//还不太懂 
int k,len;
int dfs(int pos,int m,int cnt)//原5466换成6645 
{//pos表示下标,m表示余数,cnt表示要改变的位数 
    int i,j;
    if(m==0)    
		return 1;  //当余数为0时,表示已经找到,返回1
    if(pos<0||cnt<=f[pos][m]||cnt==0)   
		return 0;
    //从前面最高位开始,从小到大遍历,保证得到的ans最小
    for(i=pos;i>=0;i--)
    {
        for(j=0;j<num[i];j++)//必须m<n 
        {
            if(i==len-1&&j==0)//(首位不可为0)  
				continue;
            ans[i]=j;
            int res=(m-(mod[i][num[i]]-mod[i][j])+k)%k; //注意+k防止出现负数
            if(dfs(i-1,res,cnt-1))    
				return 1;  //进入下一层搜索
        }
        ans[i]=num[i];  //还原ans
    }
    //从后面最低位开始,从小到大遍历,保证得到的ans最小
    for(i=0;i<=pos;i++)
    {
        for(j=num[i]+1;j<10;j++)
        {
            ans[i]=j;
            int res=(m+(mod[i][j]-mod[i][num[i]]))%k;
            if(dfs(i-1,res,cnt-1))//[i-1不太懂]    
				return 1;
        }
        ans[i]=num[i];  //还原
    }
    f[pos][m]=cnt;
    return 0;
}
int main()
{
    while(~scanf("%s",str))
    {
        int i,j;
        scanf("%d",&k);
        memset(f,0,sizeof(int)*(k+1));
        len=strlen(str);
        /*对一个超级大的数取模,需要对这个数进行拆分
 		利用(a+b)%k=(a%k+b%k)%k和(a*b)%k=(a%k*b%k)%k 
		例如 111%5=(1+10+100)%5=(1%5+10%5+100%5)%5=(1%5+(1%5*10%5)%5;*/
		//
        for(i=0;i<10;i++)   
			mod[0][i]=i%k;//个位先取模 
        for(i=1;i<len;i++)//十,百,千...取模 
            for(j=0;j<10;j++)
                mod[i][j]=(mod[i-1][j]*10)%k;     //mod[i][j]:  j*(10^i) 对 K 的取余值
        //
		int m=0;
        for(i=0;i<len;i++)//个,百,千...所有余数相加再取模[(a+b)%k=(a%k+b%k)%k,延伸到n个数相加再取模]
        {
            ans[i]=num[i]=str[len-1-i]-'0';//ans,num倒存str 
            m=(m+mod[i][ans[i]])%k;   //获得str除以k的余数m
        }
        for(i=1;i<=len;i++) 
			if(dfs(len-1,m,i))    
				break;
        for(i=len-1;i>=0;i--)   
			printf("%d",ans[i]);
  		printf("\n");
    }
    return 0;
}
# 高校智慧校园解决方案摘要 智慧校园解决方案是针对高校信息化建设的核心工程,旨在通过物联网技术实现数字化校园的智能化升级。该方案通过融合计算机技术、网络通信技术、数据库技术和IC卡识别技术,初步实现了校园一卡通系统,进而通过人脸识别技术实现了更精准的校园安全管理、生活管理、教务管理和资源管理。 方案包括多个管理系统:智慧校园管理平台、一卡通卡务管理系统、一卡通人脸库管理平台、智能人脸识别消费管理系统、疫情防控管理系统、人脸识别无感识别管理系统、议签到管理系统、人脸识别通道管理系统和图书馆对接管理系统。这些系统共同构成了智慧校园的信息化基础,通过统一数据库和操作平台,实现了数据共享和信息一致性。 智能人脸识别消费管理系统通过人脸识别终端,在无需接触的情况下快速完成消费支付过程,提升了校园服务效率。疫情防控管理系统利用热成像测温技术、视频智能分析等手段,实现了对校园人员体温监测和疫情信息实时上报,提高了校园公共卫生事件的预防和控制能力。 议签到管理系统和人脸识别通道管理系统均基于人脸识别技术,实现了议的快速签到和图书馆等场所的高效通行管理。与图书馆对接管理系统实现了一卡通系统与图书馆管理系统的无缝集成,提升了图书借阅的便捷性。 总体而言,该智慧校园解决方案通过集成的信息化管理系统,提升了校园管理的智能化水平,优化了校园生活体验,增强了校园安全,并提高了教学和科研的效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值