小红的数位删除(二进制枚举)
链接:https://ac.nowcoder.com/acm/contest/69695/D
来源:牛客网
小红拿到了两个正整数\(a\)和\(b\),她每次操作可以选择其中一个正整数,删除一个数位。例如,对于"1243"而言,进行一次操作可以生成"124"、"123"、"143"或"243"。
小红希望最终\(a\)是\(b\)的倍数或者\(b\)是\(a\)的倍数。她想知道自己最少的操作次数是多少?
输入描述:
两个正整数\(a\)和\(b\),用空格隔开。
\(1\leq a,b \leq 10^9\)
输出描述:
如果无法如何都无法使得\(a\)是\(b\)的倍数或者\(b\)是\(a\)的倍数,则输出-1。
否则输出一个整数,代表小红的最小操作次数。
示例1
输入
37 111
输出
0
说明
111是37的倍数,所以小红不需要任何操作。
示例2
输入
1234 99
输出
2
说明
第一个数删除数字'1',变成234。第二个数删除数字'9',变成9。234是9的倍数。
这个是二进制枚举
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e6+100;
int ans=1e9;
struct node{
int aa,st;
}qa[maxn],qb[maxn];
int t=0,t1=0;
void changea(char *a,char *b){
int len1=strlen(a);
int len2=strlen(b);
int d=0;
for(int i=1;i<(1<<len1);i++){
int s=0,res=0;
for(int j=0;j<len1;j++){
if((i>>j)&1){
s=s*10+(a[j]-'0');
}
else{
res++;
}
}
qa[++t].aa=s,qa[t].st=res;
}
}
void changeb(char *a,char *b){
int len1=strlen(a);
int len2=strlen(b);
int d=0;
for(int i=1;i<(1<<len1);i++){
int s=0,res=0;
for(int j=0;j<len1;j++){
if((i>>j)&1){
s=s*10+(a[j]-'0');
}
else{
res++;
}
}
qb[++t1].aa=s,qb[t1].st=res;
}
}
int main(){
char a[100],b[100];
scanf("%s%s",a,b);
//改变a
changea(a,b);
changeb(b,a);
for(int i=1;i<=t;i++){
for(int j=1;j<=t1;j++){
int z1=qa[i].aa,z2=qb[j].aa;
if(z2>z1) swap(z1,z2);
if(z1%z2==0){
ans=min(ans,qa[i].st+qb[j].st);
}
}
}
if(ans==1e9){
cout<<-1<<endl;
}
else
cout<<ans<<endl;
}