UVALive - 7511 Multiplication Table(暴力+模拟)

tech2026-08-14  5

题目链接:点击查看

题目大意:给出一个二维矩阵表示无限大的乘法表,每个位置的值都等于 i * j ,现在给出一个 n * m 的矩阵,现在需要判断该矩阵是否为乘法表的一个子矩阵

题目分析:训练时以为是联立方程然后高斯消元求秩,但时间复杂度顶不太住,于是就自己解方程去求秩,很显然这么庞大的代码实现写出了一堆bug,最后都到了懒得修改的地步

看了网上的题解后人都傻了,应该是正解,随便选一个位置枚举其因子作为 i 和 j ,然后 O( n * m ) 去扫一遍整个矩阵然后判断是否合法,但 1e9 内因子最多的一个数只有 1536 ,总的算下来时间复杂度也是 1e11 级别的,但最后 800ms 就过了,那就只能说明这个题目的数据应该比较难构造

然后就转换成一个简单的模拟题了,随便写写就好了

代码:  

#include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<unordered_map> #define double long double using namespace std; typedef long long LL; typedef unsigned long long ull; const int inf=0x3f3f3f3f; const int N=1e5+100; vector<tuple<int,int,int>>node; bool check(LL x,LL y) { for(auto t:node) { LL i,j,num; tie(i,j,num)=t; if((i+x)*(j+y)!=num) return false; } return true; }; bool solve() { if(node.empty()) return true; int num,x,y; tie(x,y,num)=node.front(); for(int i=1;i*i<=num;i++) { if(num%i) continue; int a=i,b=num/i; if(a>=x&&b>=y&&check(a-x,b-y)) return true; if(b>=x&&a>=y&&check(b-x,a-y)) return true; } return false; } int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif ios::sync_with_stdio(false); int w; cin>>w; int kase=0; while(w--) { node.clear(); int n,m; cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { string s; cin>>s; if(s=="?") continue; node.emplace_back(i,j,stoi(s)); } if(solve()) cout<<"Case #"<<++kase<<": Yes"<<endl; else cout<<"Case #"<<++kase<<": No"<<endl; } return 0; }

 

最新回复(0)