UVALive 7511 Multiplication Table (数学模拟题)

题目大意:给一个数字矩阵,'?'表示不确定的数字,问这个子矩阵可不可能存在于乘法表里

题目分析:全是问号显然可以,只有一个数字枚举约数和数字的坐标比较,大于等于两个数字,还是枚举约数判断与剩下的数字是否匹配

#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");
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值