http://codeforces.com/problemset/problem/354/E
如果从个位到最高位依次对每一位尝试所有可能(搜索):
1. 对每一位,显然4和7出现的顺序无关紧要,只需要考虑个数(预处理出所有可能的组合,如果当前位是x,直接遍历和为x的4和7的个数组合);
2. 进位的处理:除最高位外,每一位获得的进位c要从当前位x中减去(c>x时,还要向高位借位,即高位减1),如果最高位完成组合后没有进位则搜索结束。
// Lucky Number Representation # include <iostream> # include <cstring> using namespace std; int c[10]; int h[10][28 + 5]; void preprocess(void) { memset(c, 0, sizeof(c)); for (int i = 0; i <= 6; ++i) { for (int j = 0; i+j <= 6; ++j) { int t = (i*4 + j*7) % 10; h[t][ c[t]++ ] = i + j*10; } } } int n, m; char s[20]; int sol[20]; bool find_answer; void dfs(int d, int carry) { if (d == -1) { if (carry == 0) find_answer = true; return ; } int k = (s[d]-'0')-carry, p = 0; if (k < 0) { if (d == 0) return ; else { p = 1; k = (k+10) % 10; } } for (int i = 0; i < c[k]; ++i) { if (find_answer) return ; int tmp = h[k][i]; sol[m-1-d] = tmp; dfs(d-1, p+((tmp/10)*7+(tmp%10)*4)/10); } } void print_sol(void) { if (find_answer == false) { cout << "-1" << endl; return ; } char a[6][25]; memset(a, 0, sizeof(a)); for (int i = 0; i < m; ++i) { int x = sol[i] % 10; int y = sol[i] / 10; for (int j = 0; j < 6; ++j) { if (x-- > 0) a[j][i] = '4'; else if (y-- > 0) a[j][i] = '7'; else a[j][i] = '0'; } } for (int j, i = 0; i < 6; ++i) { for (j = m-1; j>=0 && (a[i][j]==0 || a[i][j]=='0'); --j) ; if (j < 0) cout << "0"; else for ( ; j >= 0; --j) cout << a[i][j]; cout << ' '; } cout << endl; } int main() { preprocess(); cin >> n; while (n--) { cin >> s; m = strlen(s); memset(sol, 0, sizeof(sol)); find_answer = false; dfs(m-1, 0); print_sol(); } return 0; }