有 n 个 (1, 9) 的数字,用这些数字填满一个三位数成两位数的乘法竖式,满足竖式上的所有数都是所给数字构成,且竖式成立,相乘结果只能为四位数,求方案数。
暴力枚举,然后模拟
#include <cstdio>
using namespace std;
int n, a[15], p1[6005], p2[6005], b[5], tot1 = 0, tot2 = 0, ans = 0;
bool vis[1000], used[15];
int main()
{
freopen("crypt1.in", "r", stdin);
freopen("crypt1.out", "w", stdout);
scanf("%d", &n);
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]), used[a[i]] = 1;
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
for(int k = 1; k <= n; k ++){
if(!vis[a[i] * 100 + a[j] * 10 + a[k]])
p1[++ tot1] = a[i] * 100 + a[j] * 10 + a[k],
vis[a[i] * 100 + a[j] * 10 + a[k]] = 1;
}
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
if(!vis[a[i] * 10 + a[j]])
p2[++ tot2] = a[i] * 10 + a[j],
vis[a[i] * 10 + a[j]] = 1;
for(int i = 1; i <= tot1; i ++)
for(int j = 1; j <= tot2; j ++){
int t1 = p1[i] * (p2[j] % 10), t2 = p1[i] * (p2[j] / 10);
int cnt = 0; bool ok = 1;
while(t1){
b[++ cnt] = t1 % 10;
t1 /= 10;
}
if(cnt != 3) continue;
for(int k = 1; k <= cnt; k ++) if(!used[b[k]]) { ok = 0; break; }
if(!ok) continue;
cnt = 0;
while(t2){
b[++ cnt] = t2 % 10;
t2 /= 10;
}
if(cnt != 3) continue;
for(int k = 1; k <= cnt; k ++) if(!used[b[k]]) { ok = 0; break; }
if(!ok) continue;
int t3 = p1[i] * p2[j];
cnt = 0;
while(t3){
b[++ cnt] = t3 % 10;
t3 /= 10;
}
if(cnt != 4) continue;
for(int k = 1; k <= cnt; k ++) if(!used[b[k]]) { ok = 0; break; }
if(!ok) continue;
if(t2 * 10 + t1 != t3) ok = 0;
if(!ok) continue;
ans ++;
}
printf("%d\n", ans);
return 0;
}