题解 矩阵

传送门

大家好,我是T3的良心出题人,你们看,别人造的数据又是链又是菊花,还有把链和菊花结合起来造蒲公英的
你们看我就不一样,我造的数据最水了,这数据都是nm都等于1的,这不随便过么?
我只不过是把nm都等于1的数据在每个subtask里都放了一个而已,你们为什么要骂我?你们凭什么骂我?

(整活向,勿喷)

好了这个题直接暴力BFS是 \(nlog^2n\)
因为链长最多logn,所以每个点最多BFS到一个 \(2logn*2logn\) 的矩形
考场上没想出来复杂度证明,只是觉得严重跑不满
然后特殊处理一下到同一个点且公比相同的情况即可

Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 40010
#define ll long long
#define make make_pair
//#define int long long

char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
	int ans=0, f=1; char c=getchar();
	while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
	while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
	return ans*f;
}

int n, m;
int **mp;

namespace force{
	int ans=1;
	const int dlt[][2]={{-1,0},{1,0},{0,1},{0,-1}};
	struct tpl{
		int x, y, div, len;
		tpl(){}
		tpl(int a, int b, int c, int d):x(a),y(b),div(c),len(d){}
	};
	queue<tpl> q;
	map<pair<pair<int, int>, int>, bool> s;
	int calc(int a, int b) {
		int ans=1;
		s.clear();
		while (q.size()) q.pop();
		for (int k=0; k<4; ++k) {
			int x=a+dlt[k][0], y=b+dlt[k][1];
			if (x>=1&&x<=n&&y>=1&&y<=m) {
				int div=mp[x][y]/mp[a][b];
				if (mp[a][b]*div==mp[x][y]) q.push(tpl(x, y, div, 2)); //, cout<<"st: "<<x<<' '<<y<<endl;
			}
		}
		tpl u;
		while (q.size()) {
			u=q.front(); q.pop();
			// cout<<"u: "<<u.x<<' '<<u.y<<endl;
			ans=max(ans, u.len);
			int x=u.x, y=u.y;
			for (int k=0,x2,y2; k<4; ++k) {
				x2=x+dlt[k][0], y2=y+dlt[k][1];
				if (x2>=1&&x2<=n&&y2>=1&&y2<=m) {
					// cout<<"x2y2: "<<x2<<' '<<y2<<endl;
					if (mp[x][y]*u.div==mp[x2][y2] && s.find(make(make(x2, y2), u.div))==s.end()) {
						q.push(tpl(x2, y2, u.div, u.len+1));
						s[make(make(x2, y2), u.div)]=1;
					}
				}
			}
		}
		return ans;
	}
	void solve() {
		for (int i=1; i<=n; ++i) for (int j=1; j<=m; ++j) {
			for (int k=0; k<4; ++k) {
				int x=i+dlt[k][0], y=j+dlt[k][1];
				if (x>=1&&x<=n&&y>=1&&y<=m&&mp[i][j]==mp[x][y]) {puts("-1"); exit(0);}
			}
		}
		for (int i=1; i<=n; ++i) for (int j=1; j<=m; ++j) ans=max(ans, calc(i, j));
		printf("%d\n", ans);
		exit(0);
	}
}

namespace task1{
	int ans=1;
	int a[N];
	void solve() {
		for (int i=1; i<=n; ++i) a[i]=mp[i][1];
		for (int i=2; i<=n; ++i) if (a[i]==a[i-1]) {puts("-1"); exit(0);}
		for (int i=1,lst=0,len=0; i<=n; ++i) {
			if (!lst) {
				if (i!=1) {
					lst=a[i]/a[i-1];
					if (a[i-1]*lst!=a[i]) lst=0, len=1;
					else len=2, ans=max(ans, len);
				}
				else lst=0, len=1;
			}
			else {
				if (a[i-1]*lst==a[i]) ++len, ans=max(ans, len);
				else {
					if (a[i-1]*lst!=a[i]) lst=0, len=1;
					else len=2, ans=max(ans, len);
				}
			}
		}
		printf("%d\n", ans);
		exit(0);
	}
}

signed main()
{
	freopen("matrix.in", "r", stdin);
	freopen("matrix.out", "w", stdout);

	n=read(); m=read();
	mp=new int*[n+2];
	for (int i=0; i<=n+1; ++i) {
		mp[i]=new int[m+2];
		for (int j=0; j<=m+1; ++j) mp[i][j]=0;
	}
	bool all_same=1; int lst;
	for (int i=1; i<=n; ++i) {
		for (int j=1; j<=m; ++j) {
			mp[i][j]=read();
			if (i==1&&j==1) lst=mp[i][j];
			else if (mp[i][j]!=lst) all_same=0;
		}
	}
	if (n*m>1 && all_same) {puts("-1"); return 0;}
	else if (m==1) task1::solve();
	else force::solve();

	return 0;
}
posted @ 2021-10-31 10:24  Administrator-09  阅读(10)  评论(0编辑  收藏  举报