题目大意:给一个数字矩阵,'?'表示不确定的数字,问这个子矩阵可不可能存在于乘法表里
题目分析:全是问号显然可以,只有一个数字枚举约数和数字的坐标比较,大于等于两个数字,还是枚举约数判断与剩下的数字是否匹配
#include <cstdio>
#include <cstring>
#include <cmath>
int const MAX = 1005;
double const EPS = 1e-10;
struct NUM
{
int x, y, val;
}num[MAX * MAX];
char s[MAX][9];
int main()
{
int T, n, m;
scanf("%d", &T);
for(int ca = 1; ca <= T; ca ++)
{
printf("Case #%d: ", ca);
int cnt = 0;
scanf("%d %d", &n, &m);
for(int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++)
{
scanf("%s", s[j]);
if(s[j][0] != '?')
{
num[cnt].x = i + 1;
num[cnt].y = j + 1;
sscanf(s[j], "%d", &num[cnt ++].val);
}
}
}
if(cnt == 0)
{
printf("Yes\n");
continue;
}
if(cnt == 1)
{
bool f = false;
int x_, y_;
for(int i = 1; !f && i <= (int)sqrt(num[0].val * 1.0); i++)
{
if(num[0].val % i == 0)
{
x_ = i;
y_ = num[0].val / i;
if((num[0].x <= x_ && num[0].y <= y_) || (num[0].y <= x_ && num[0].x <= y_))
f = true;
}
}
printf("%s\n", f ? "Yes" : "No");
continue;
}
int x1, y1;
bool f = false;
for(int i = 1; !f && i <= (int)sqrt(num[0].val * 1.0); i++)
{
if(num[0].val % i == 0)
{
x1 = i;
y1 = num[0].val / i;
if(x1 >= num[0].x && y1 >= num[0].y)
{
if((x1 + num[1].x - num[0].x) * (y1 + num[1].y - num[0].y) == num[1].val)
{
bool f2 = true;
for(int j = 2; f2 && j < cnt; j++)
if((x1 + num[j].x - num[0].x) * (y1 + num[j].y - num[0].y) != num[j].val)
f2 = false;
if(f2)
f = true;
}
}
if(y1 >= num[0].x && x1 >= num[0].y)
{
if((y1 + num[1].x - num[0].x) * (x1 + num[1].y - num[0].y) == num[1].val)
{
bool f2 = true;
for(int j = 2; f2 && j < cnt; j++)
if((y1 + num[j].x - num[0].x) * (x1 + num[j].y - num[0].y) != num[j].val)
f2 = false;
if(f2)
f = true;
}
}
}
}
printf("%s\n", f ? "Yes" : "No");
}
}