点我看题
题意 给出一种运算方式的定义
给出结果串 和 A串 B串的长度
要你构造出字典序最小的A串和B串。
解题思路:
遇到这种题,应该把相关的表尽量打出来。
上来先打个 九九乘法表
发现 对于每一位数字xy =z 通过z的首位数字,就可以判断z的长度。
除0外 可以通过x 和z唯一确定y。 这样的话 就可在9nm的复杂度内得出答案。
又发现,虽然nm有1e10 这么多,但是 对于有解的n*m必定小于2e5
这样,这道题就变成了一道暴力求解的题了。
感觉很有意思
#include<bits/stdc++.h>
using namespace std;
int lens[10][10];
int neednum[10][100];
long long n,m;
void init(){
memset(neednum,-1,sizeof neednum);
for(int i=0;i<=9;i++){
for(int j=0;j<=9;j++){
if(i*j>9){
lens[i][(i*j)/10]=2;
}else{
lens[i][i*j]=1;
}
if(i*j!=0)
neednum[i][i*j]=j;
else
neednum[i][i*j]=0;
}
}
}
const int MAX= 2e5+10;
char str[MAX];
int a[MAX],b[MAX];
bool judge(int now,int &index){
if(now>9){
if(str[index]-'0'==now/10 && str[index+1]-'0'==now%10){
index+=2;
return 1;
}else{
return 0;
}
}else{
if(str[index]-'0'==now){
index++;
return 1;
}else{
return 0;
}
}
}
long long len ;
bool check(int x){
memset(a,-1,sizeof a);
memset(b,-1,sizeof b);
a[1]=x;
int index = 0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i]!=-1 && b[j]!=-1){
if(!judge(a[i]*b[j],index)){
return 0;
}
}else if(a[i]!=-1){
int clen = lens[a[i]][str[index]-'0'];
if(clen==1){
b[j]=neednum[a[i]][str[index]-'0'];
}else{
b[j]=neednum[a[i]][(str[index]-'0')*10+(str[index+1]-'0')];
}
if(b[j]==-1) return 0;
index+=clen;
}else{
int clen = lens[b[j]][str[index]-'0'];
if(clen==1){
a[i]=neednum[b[j]][str[index]-'0'];
}else{
a[i]=neednum[b[j]][(str[index]-'0')*10+(str[index+1]-'0')];
}
if(a[i]==-1) return 0;
index+=clen;
}
}
}
return index>=len;
}
int main(){
init();
int T;
scanf("%d",&T);
while(T--){
scanf("%lld %lld",&n,&m);
scanf("%s",str);
len = strlen(str);
if(n*m>len || n*m*2<len){
puts("Impossible");
continue;
}
int flag= 0;
for(int i=0;i<=9;i++){
if(check(i)){
flag= 1;
break;
}
}
if(flag){
for(int i=1;i<=n;i++){
printf("%d",a[i]);
}
printf(" ");
for(int j=1;j<=m;j++){
printf("%d",b[j]);
}
puts("");
}else{
puts("Impossible");
}
}
return 0;
}