题解 P6380 【『MdOI R2』Mayuri】
看了看题解区的题解,纠结了一下还是把官方题解发出来吧。
感觉做的都比较麻烦,仅有的几个贪心写法的基本也都没给证明。
以下是官方题解。
首先,我们分析输出 -1 的情况。
容易发现,当 1 时显然无解,具体证明同样例二。
除此以外的情况都是有解的。证明如下:
对于
假设对于
假设
则只需证明
熟知对于任意正整数
由于
故它们中必定有一个数为
故在接下来的讨论中排除无解的情况。
Subtask 1:
由于 0 ,则
如果输入的串是
Subtask 2:
对于
我们也可以采用枚举所有两位数逐个判断的方式。
当我们判断某一个数是否符合条件时,我们通过除以
如果第一位符合条件,我们再直接判断其是否整除
Subtask 3:
与上面的做法相似,直接枚举所有
不同的是对于每一个数我们要判断
我们通过除以
对于每个数,逐一判断。先分离其第一位判断是否满足条件,若满足则分离前两位,以此类推。
由于
Subtask 4:
要判断一个数是否是
所以我们可以考虑从高位开始往后添加数字。
如果某一位是 1 ,则我们需要添加的数字是
同理,如果某一位是 0 则我们选择添加一个
另外,如果字符串的第一位是 1 ,则我们需要进行特判。
Subtask 5:
考虑延续上面的做法,从高位往后添加数字。
由于我们是在高位上添加的,因此我们只需保证我们添加的数字最小,就一定是最优的。
对于第一位,如果第一位的字符是 0 则我们添加
然后对于后面的每一位,设我们当前的数是
由于
另外,由于
以下是 std 代码。
#include <bits/stdc++.h>
using namespace std;
char c[100005],n[100005];
int a,b;
int now;
int main(){
cin>>a>>b>>c;
if(c[0]=='0')n[0]='1',now=1;
else{
if(a==10){
puts("-1");
return 0;
}
else n[0]=a+'0';
};
for(int i=1;i<b;i++){
now*=10;
for(int j=0;j<=9;j++)
if((now+j)%a==0&&c[i]=='1'||(now+j)%a!=0&&c[i]=='0'){
now+=j;
now%=a;
n[i]=j+'0';
break;
}
}
cout<<n;
return 0;
}