Multiplication Table
题目链接:Multiplication Table
题意:给一个数字矩阵, ? 表示不确定的数字,问这个子矩阵是否可能存在于乘法表里
思路:当子矩阵中都是
当子矩阵中只有一个数时,我们只需要验证这个数是否合法(其约数≥其坐标位置)
当子矩阵中有两个或者多个数时,我们可以枚举第一个数的约数来确定这个矩阵的位置,然后再验证其他位置上的数是否正确即可
代码:
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=1e3+10;
int num[maxn][maxn],p[maxn][2];
int n,m,sum;
bool flag;
int Change(char s[])
{
int tot=0;
for(int i=0; i<strlen(s); ++i)
tot=tot*10+s[i]-'0';
return tot;
}
bool Judge_one()//只有一个数时,判断这个数是否合理
{
int x=p[1][0],y=p[1][1];
int tot=num[x][y];
for(int i=1; i<=sqrt(tot*1.0); ++i)
if(tot%i==0&&((i>=x&&tot/i>=y)||(i>=y&&tot/i>=x)))
return true;
return false;
}
bool Judge_more()//多个数
{
int x=p[1][0],y=p[1][1];
int tot=num[x][y];
for(int i=1; i<=sqrt(tot*1.0); ++i)
{
if(tot%i==0)
{
int a=i,b=tot/i;
if(a>=x&&b>=y)
{
bool flog=true;
for(int j=2; j<=sum&&flog; ++j)
if((a-x+p[j][0])*(b-y+p[j][1])!=num[p[j][0]][p[j][1]])
flog=false;
if(flog)
return true;
}
if(b>=x&&a>=y)
{
bool flog=true;
for(int j=2; j<=sum&&flog; ++j)
if((b-x+p[j][0])*(a-y+p[j][1])!=num[p[j][0]][p[j][1]])
flog=false;
if(flog)
return true;
}
}
}
return false;
}
int main()
{
int t,k=0;
char s[20];
scanf("%d",&t);
while(++k<=t)
{
sum=0;
memset(num,0,sizeof(num));
scanf("%d%d",&n,&m);
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j)
{
scanf("%s",s);
if(s[0]!='?')
num[i][j]=Change(s),p[++sum][0]=i,p[sum][1]=j;
}
if(!sum)
flag=true;
else if(sum==1)
flag=Judge_one();
else
flag=Judge_more();
if(flag)
printf("Case #%d: Yes\n",k);
else
printf("Case #%d: No\n",k);
}
return 0;
}