2018青岛D

题意

懒得说了

题解

枚举 A A A的第一位,得到 B B B
保证得到的都是个位数。
这样是可以的,因为不会存在个位数相乘既可以得到个位数又可以得到两位数。

通过 B B B反过来得到 A A A。每次找 A A A的时候保证得到的 A A A是同一个值。
保证可以得到值(可能找不到合法的)
保证不会提前到终点( A A A数组还没构造完)
保证个位数
保证 B B B数组每次都查询完毕

#include<bits/stdc++.h>
using namespace std;

const int maxn = 2e5 + 5050;

int n,m,len;
int A[maxn],B[maxn],C[maxn];

bool slove1(int x){
    int now=1,val=0,id=0;
    while(now<=len&&id<m){
        val=val*10+C[now];
        if(val%x==0){
            if(val/x>10)return false;
            B[++id]=val/x;
            val=0;
        }
        else if(val>10)return false;
        now++;
    }
    return id==m;
}

int slove2(int aid,int pos){
    int now=pos,val=0,id=1;
    int ret=-1;
        while(now<=len&&id<=m){
            val=val*10+C[now];
            if(B[id]==0){
                if(val!=0)return false;
                id++,val=0;
            }
            else if(val%B[id]==0){
                if(val/B[id]>10)return false;
                if(ret==-1)ret=val/B[id];
                else if(ret!=val/B[id])return -1;
                id++,val=0;
            }
            else if(val>10)return -1;
            now++;
        }
    if(ret==-1||id!=m+1)return false;
    A[aid]=ret;
    if(now==len+1){
        if(aid==n)return now;
        else return -1;
    }//提前结束是不对的。
    else return now;
}

int main(){
    int T;cin>>T;
    while(T--){
        len=0;
        scanf("%d%d",&n,&m);
        string str;cin>>str;
        for(auto ch:str)C[++len]=ch-'0';
        bool ok=false;
        for(int i=1;i<=9;i++){
            if(!slove1(i))continue;
           // cout<<i<<":"<<endl;
            //for(int j=1;j<=m;j++)printf("%d",B[j]);puts("");
            int tmp=1;
            for(int j=1;j<=n;j++){
                tmp=slove2(j,tmp);
                if(tmp==-1)break;
            }
            if(tmp!=len+1)continue;
            ok=true;
            break;
        }
        if(ok){
            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");
        }
        else puts("Impossible");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值