UVALive 7511Multiplication Table

来源:互联网 发布:磐石投票软件 编辑:程序博客网 时间:2024/06/14 12:21

题意; 给出一个矩阵,询问是否能从乘法表中找出他的位置

思路:

对于每个数字 如果他可以拆解为 x1 *y1  x2*y2那么他必定有可能出现在X1行Y1列, X2行Y2列。那么如果已知了两个数字,那我们就直接可以确定

他在哪个矩阵部分。 那么我们就可以用这个矩阵验证已知的每一项。

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int N = 1e3 + 50;ll prim[10][N], a[N][N];ll x[10], y[10], tot[10], cnt;char s[N];ll get(){ll num = 0;if(s[0] == '?') return -1;for(int i = 0; i < strlen(s); i++) num = num * 10 + s[i] - '0';return num; }void split(ll num){for(ll i = 1; i * i <= num; i++){if(num % i == 0) {prim[cnt][++tot[cnt]] = i;prim[cnt][++tot[cnt]] = num / i;}}}int main(){int T;scanf("%d", &T);for(int kase = 1; kase <= T; kase++){ll n, m;cnt = 0;memset(tot, 0, sizeof(tot));memset(x, 0, sizeof(x));memset(y, 0, sizeof(y));memset(a, 0, sizeof(a));memset(prim, 0, sizeof(prim));scanf("%lld%lld", &n, &m);for(ll i = 1; i <= n; i++){for(ll j = 1; j <= m; j++){scanf("%s", s);a[i][j] = get();if (cnt == 2) continue;if(a[i][j] != -1) {cnt++;x[cnt] = i, y[cnt] = j;split(a[i][j]);}}}printf("Case #%d: ", kase);int ok = 1, tx = 0;if(cnt == 0) {puts("Yes");continue;}else if(cnt == 1) {ok = 0;ll num = a[x[1]][y[1]];for(ll i = 1; i <= tot[1]; i++) {//cout << prim[1][i] << " " << num / prim[1][i] << endl;if(prim[1][i] - x[1] + 1 > 0 && num / prim[1][i] - y[1] + 1 > 0) ok = 1;//cout << ok << endl;}}else {for(ll i = 1; !tx && i <= tot[1]; i++) {for(ll j = 1; !tx && j <= tot[2]; j++) {ll num1 = a[x[1]][y[1]], num2 = a[x[2]][y[2]];ll x1 = prim[1][i], y1 = num1 / prim[1][i], x2 = prim[2][j], y2 = num2 / prim[2][j];if(x1 - x2 == x[1] - x[2] && y1 - y2 == y[1] - y[2]) {tx = i;}}}ll num = a[x[1]][y[1]];if(prim[1][tx] - x[1] + 1 < 1 || num / prim[1][tx] - y[1] + 1 < 1) ok = 0;else {ll zx = prim[1][tx] - x[1] + 1, zy = num / prim[1][tx] - y[1] + 1;for(ll i = 1; i <= n; i++){for(ll j = 1; j <= m; j++){ll num = (zx + i - 1) * (zy + j - 1);if(a[i][j] != -1 && a[i][j] != num) ok = 0; }} }}if(ok) puts("Yes");else puts("No");}return 0;}


原创粉丝点击