[ACdream]小晴天老师系列——竖式乘
题目链接:http://acdream.info/contest?cid=1269#problem-C
Problem Description
小晴天是ACdream团队中最牛的老师之一,他最擅长数学运算~这天他翻开一本《AC is not a dream》杂志,发现最后一页有一道很经典的思维题,题目很简单,每个框填写一个数字,构成一个竖式,每个数的最高位不能为0,但是有一些数字被隐藏掉了,然后让你根据没有隐藏的数字填出隐藏的数字。
如下图:
然后小晴天二话不说,三下五除二就写出了答案:
然后小晴天就觉得这样的题目太简单了,于是问你是否有办法来求出一道题目有多少种不同的答案呢?(只要有一个方框有不同的数字即为不同的答案)
Input
多组数据,首先是一个整数t(t<=20),表示数据组数。
对于每组数据,用5行表示一个竖式,每行均为一个字符串,仅含有星号(*)与数字('0'~'9')组成,其中星号表示空白
其中第一行为长度为3的字符串。
第二行为长度为2的字符串。
第三行为长度为4的字符串。
第四行为长度为3的字符串。
第五行为长度为5的字符串。
Output
对于每组数据,输出一个整数x,表示符合乘法竖式法则的填法的种类。
Sample Input
2 *** ** 3384 846 ***** 4** ** 3384 846 *****
Sample Output
2 1
解题思路:
题上就是实现一个三位数乘以一个两位数的过程,而且该三位数乘以十位数的各位等于四位数,乘以十位等于三位数,最后得到的是五位数,但是有一些限制条件,就是在这五行中有的位置上的数字已经给出来了,让你找符合的条件的个数;
我的做法就是,用两个for循环一个是三位数,以为是两位数,在用一个判断函数,看看这三位数跟两位数是不是符合题上给的条件,如果符合就继续,把该三位数乘以两位数个位数看是否满足四位数且满足题上给的四位数条件,还有该三位数乘以两位数的十位是否是三位数且也满足题目上给的条件,这些都满足后,在把得到的计算后的四位数加上三位数*10(注:因为是乘法运算右移了一位)看是否满足五位数且也符合题上该行的条件,如果这也满足就是其中符合条件的一个了。
AC代码:
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<algorithm> using namespace std; char a[10][10]; int judge1(int x) { int a1,b,c,d,e,f; if(x>=10&&x<100) { a1=x/10;b=x%10; if(a[1][0]!='*'&&a[1][0]-'0'!=a1) return 0; if(a[1][1]!='*'&&a[1][1]-'0'!=b) return 0; } else if(x>=100&&x<1000) { a1=x/100;b=(x%100)/10;c=x%10; if(a[0][0]!='*'&&a[0][0]-'0'!=a1) return 0; if(a[0][1]!='*'&&a[0][1]-'0'!=b) return 0; if(a[0][2]!='*'&&a[0][2]-'0'!=c) return 0; } else if(x>=1000&&x<10000) { a1=x/1000;b=(x%1000)/100;c=(x%100)/10;d=x%10; if(a[2][0]!='*'&&a[2][0]-'0'!=a1) return 0; if(a[2][1]!='*'&&a[2][1]-'0'!=b) return 0; if(a[2][2]!='*'&&a[2][2]-'0'!=c) return 0; if(a[2][3]!='*'&&a[2][3]-'0'!=d) return 0; } else if(x>=10000) { a1=x/10000;b=(x%10000)/1000;c=(x%1000)/100;d=(x%100)/10;e=x%10; if(a[4][0]!='*'&&a[4][0]-'0'!=a1) return 0; if(a[4][1]!='*'&&a[4][1]-'0'!=b) return 0; if(a[4][2]!='*'&&a[4][2]-'0'!=c) return 0; if(a[4][3]!='*'&&a[4][3]-'0'!=d) return 0; if(a[4][4]!='*'&&a[4][4]-'0'!=e) return 0; } return 1; } int judge2(int x) { int a1,b,c,d; a1=x/100;b=(x%100)/10;c=x%10; if(a[3][0]!='*'&&a[3][0]-'0'!=a1) return 0; if(a[3][1]!='*'&&a[3][1]-'0'!=b) return 0; if(a[3][2]!='*'&&a[3][2]-'0'!=c) return 0; return 1; } int main() { int i,j,k,tcase,sum; scanf("%d",&tcase); while(tcase--) { sum=0; int m,n; for(i=0; i<5; i++) scanf("%s",a[i]); for(i=100; i<=999; i++) { for(j=10; j<=99; j++) { m=((j%10)*i);n=((j/10)*i); if(judge1(i)&&judge1(j)&&m<10000&&m>=1000&&n<1000&&n>=100) { if(judge1(m)&&judge2(n)) { if(m+n*10>=10000&&judge1(m+n*10)) sum++; } } } } printf("%d\n",sum); } return 0; }