題目鏈接:點擊查看
題目大意:給出一個二維矩陣表示無限大的乘法表,每個位置的值都等于 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);
#endifios::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;elsecout<<"Case #"<<++kase<<": No"<<endl;}return 0;
}
?
總結
以上是生活随笔為你收集整理的UVALive - 7511 Multiplication Table(暴力+模拟)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。