来一发 vector 的(vector 大法好)
思索题面显然不能爆搜。但是看到 47 和 74 很容易得出,我们先把这 n n nn nn 个 47 和 m m mm mm 个 74 骨架搭好,再进一步往里填充多余的4 与 7 即可。
例如: 5 8 3 2 ----> 由于 n n ≥ m m nn \ge mm nn≥mm, 我们先有 474747 这个骨架,由于题目要求这个数最小(然鹅翻译没提到,望 update ),我们把剩余的 4 、7 填充, 4 放在最前面的 4 后, 7 放最后的 7 后,按此规律摆放即可。当搭骨架时,某些个数不够用了,就认为无解。当 n n < m m nn < mm nn<mm 时同理。
特别注意的是,当 n n = m m nn = mm nn=mm 时,可能 4 在开头行不通而 7 在开头可行,就需要进行两次判断了。
code–>
#include <cstdio>
#include <vector>
#include <cmath>
#include <cctype>
#define PT 520
using namespace std;
int n, m, nn, mm, fl, kn, km, knn, kmm;
vector <int> a[2000006];//特别注意要开到 2*10^6 以上,不然会RE
int read()
{
int s = 0, f = 1;
char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') f = -1;
ch = getchar();
}
while(isdigit(ch)) {
s = (s << 3) + (s << 1) + ch - '0';
ch = getchar();
}
return s * f;
}
int main(){
kn = n = read(), km = m = read(), knn = nn = read(),kmm = mm = read();
if(nn >= mm) {
int k = nn + mm;
a[1].push_back(1), --n;
for(int i = 2; i <= k + 1; i++){//here is 搭骨架
if(i % 2 == 1){
if(!mm || !n) {//第一次不行,跑到下面再来一次
goto there;
}
a[i].push_back(1), --mm, --n;
}
else{
if(!nn || !m){//同上
goto there;
return 0;
}
a[i].push_back(2), --nn, --m;
}
}
while(n--){//here is 填充
a[1].push_back(1);
}
int w = k + 1;
if(!(k % 2)) w--;
while(m--){
a[w].push_back(2);
}
for(int i = 1; i <= k + 1; ++i)
for(int j = 0; j < a[i].size() ; ++j)
if(a[i][j] == 1)
printf("4");
else printf("7");
}
else {
there:;//由于 coder 的懒惰,nn > mm 时也再跑了一次,但这无伤大雅
n = kn, m = km, mm = kmm, nn = knn;//这里先回归原始条件
for(int i = 1; i <= mm + nn + 1; ++i)
a[i].clear() ;
int k = nn + mm;
a[1].push_back(1), --m;
for(int i = 2; i <= k + 1; i++){
if(i % 2 == 1){
if(!nn || !m) {
printf("-1\n");
return 0;
}
a[i].push_back(1), --nn, --m;
}
else{
if(!mm || !n){
printf("-1\n");
return 0;
}
a[i].push_back(2), --mm, --n;
}
}
while(n--){
a[2].push_back(2);
}
int w = k + 1;
if(k % 2) w--;
while(m--){
a[w].push_back(1);
}
for(int i = 1; i <= k + 1; ++i)
for(int j = 0; j < a[i].size() ; ++j)
if(a[i][j] == 1)
printf("7");
else printf("4");
}
return 0;
}
完结撒花✿✿ヽ(°▽°)ノ✿