4061 Magic Multiplication (直接模擬)
阿新 • • 發佈:2018-12-20
青島…… 沒想到我大三了還會打鐵 果然是太菜了
題意是兩個數A,B上每一位相乘,然後順次接在一起,現在給你結果C和原來兩個數字的長度,要求恢復成原來的數字A,B。
兩個個位數想乘,結果一定是小於等於兩位的。我們首先能想到列舉A的第一個數字,然後用C恢復B,然後用B恢復A,中途判斷能不能構成C就行。相當於每次搜都走一次C的長度,時間複雜度基本上是的,從資料上看不會超時。 如果暴力搜的話,會發現其實有很多取一位還是取兩位的問題,我們要是能把這個地方優化掉,就不用回溯了。 我們列出99乘法表……會發現這樣的規律: 兩位數的乘積,第一位一定是小於這兩個數的 這樣就好辦了,我們利用這個就能一次性判斷這個位數了
#include <bits/stdc++.h>
#include <cstring>
#define ll long long
#define endl '\n'
using namespace std;
const int MAXN = 2e5 + 10;
char s[MAXN];
int a[MAXN],b[MAXN],c[MAXN];
int main()
{
// freopen("input.txt","w",stdout);
// data_gene(10000);
//freopen("input.txt","r",stdin);
int ca;
scanf("%d",&ca);
while(ca--)
{
int n,m;
scanf("%d %d",&n,&m);
scanf("%s",s);
int clen = strlen(s);
for(int i = 0; i<clen; ++i)
c[i] = s[i]-'0';
bool ok = 0;
for(int a1 = 1; a1 <= 9; ++a1)
{
int f = 1,p = 0;
for(int i = 1; i<=m; ++i)
{
int t1 = c[p];
if(t1 == 0)
{
p++;
b[i] = 0;
}
else if(t1 < a1)
{
t1 = t1 * 10 + c[p+1];
if(t1 % a1 != 0)
{
f = 0;
break;
}
b[i] = t1/a1;
p+=2;
}
else
{
if(t1 % a1 != 0)
{
f = 0;
break;
}
b[i] = t1/a1;
p++;
}
}
if(!f)
continue;
a[1] = a1;
for(int i = 2; i<=n; ++i)
{
int t1 = c[p];
int ta;
if(t1 == 0)
{
ta = 0;
p++;
}
else if(t1 < b[1])
{
t1 = t1*10 + c[p+1];
if(t1 % b[1] != 0)
{
f = 0;break;
}
p+=2;
ta = t1/b[1];
}
else
{
p++;
if(t1 % b[1] != 0)
{
f = 0;break;
}
ta = t1/b[1];
}
bool ff = 1;
for(int j = 2; j<=m; ++j)
{
int t2 = ta*b[j];
if(t2 == c[p])
{
p++;
}
else if(t2 == c[p]*10 + c[p+1])
p+=2;
else
{
ff = 0;
break;
}
}
if(ff)
a[i] = ta;
else
{
f = 0;
break;
}
}
if(!f)
continue;
if(p != clen)
continue;
ok = 1;
for(int i =1; i<=n; i++)
printf("%d",a[i]);
printf(" ");
for(int i = 1; i<=m; i++)
printf("%d",b[i]);
printf("\n");
break;
}
if(!ok)
puts("Impossible");
}
return 0;
}