#13 WA 是什么情况?
查看原帖
#13 WA 是什么情况?
507348
__vector__楼主2024/4/2 12:56

95pts..........

做法:
观察发现每个路径都可以对应到底部的一个点,且底部每个点都只对应一条路径。 。

对于底部每个点,O(n)O(n) 预处理该点路径的点权和,以及所涉及哪些直线,将其解析式记录。

然后枚举底部两个点,将其对应路径点权和相加,并通过小学数学求直线交点的方式减去重合部分。

O(n2)O(n^2)

#include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define REP(i,a,b) for(int i=a;i>=b;i--)
typedef long long ll;
template<class T>
void ckmx(T& a,T b) {
	a=max(a,b);
}
template<class T>
void ckmn(T& a,T b) {
	a=min(a,b);
}
const int maxn=1005;
int n;
int a[maxn][maxn];
int flval[maxn];// 底部向左,右的值综合
struct Line {
	int k,b;
	int get(Line& l2) {
		// 求交点的值
		int k2=l2.k,b2=l2.b;
		if(k==k2)return 0;
		int x=(b2-b)/(k-k2);
		if(x<0||x>n)return 0;
	//	printf("%dx+%d with %dx+%d\n",k,b,k2,b2);
		if(x*(k-k2)==(b2-b)) {
			int y=k*x+b;
	//		puts("ok");
			if(y<=n) 
				return a[x][y];
			return 0;
		} else {
			return 0;
		}
	}
} lefup,rigup,flup;
Line mkli(int x1,int y1,int x2,int y2) {
	int k=(y2-y1)/(x2-x1);
	// kx1+b=y1
	// kx1=y1-b
	// b+kx1=y1
	// b= (y1-kx1)
	int b=y1-k*x1;
	Line res;
	res.k=k;
	res.b=b;
	return res;
}
vector<Line> f[maxn];
int un(int i,int j) {
	int ans=0;
	for(auto u:f[i]) {
		for(auto v:f[j]) {
			ans+=u.get(v);
		}
	}
	return ans;
}
int tmp[maxn];
int main() {
	scanf("%d",&n);
	FOR(i,1,n) {
		FOR(j,1,n) {
			scanf("%d",&a[i][j]);
		}
	}
	FOR(j,1,n){
		FOR(i,1,n){
			tmp[n-i+1]=a[i][j];
		}
		FOR(i,1,n){
			a[i][j]=tmp[i];
		}
	}
	f[1].emplace_back(mkli(1,1,n,n));
	int hang=1,lie=1;
	while(hang<=n){
		flval[1]+=a[hang][lie];
		hang++;
		lie++;
	}
	f[n].emplace_back(mkli(1,n,n,1));
	hang=1,lie=n;
	while(hang<=n){
		flval[n]+=a[hang][lie];
		hang++;
		lie--;
	}
//	printf("%d %d\n",flval[1],flval[n]);
	FOR(i,2,n-1) {
	//	printf("i = %d\n",i);   
		// 计算到左部/右部,之后的坐标
		int y_lef=i;
		int y_rig=n-i+1;
	//	printf("%d %d\n",y_lef,y_rig);
		f[i].emplace_back(mkli(1,i,y_lef,1));
		f[i].emplace_back(mkli(1,i,y_rig,n));
		int hang=1,lie=i;
		while(hang!=y_lef) {
			flval[i]+=a[hang][lie];
			hang++;
			lie--;
		}
		flval[i]+=a[hang][lie];
	//	printf("current = %d\n",flval[i]);
		int hang2=1,lie2=i;
		while(hang2!=y_rig) {
			hang2++;
			lie2++;
			flval[i]+=a[hang2][lie2];
		}
//		printf("current = %d\n",flval[i]);
	//	printf("hang %d %d hang2 %d %d\n",hang,lie,hang2,lie2);
		int hang3=hang,lie3=lie;
		while(hang3!=n) {
			hang3++;
			lie3++;
			flval[i]+=a[hang3][lie3];
		}
	//	printf("current = %d\n",flval[i]);
		f[i].emplace_back(mkli(hang,lie,hang3,lie3));
		int hang4=hang2,lie4=lie2;
		while(hang4!=n) {
			hang4++;
			lie4--;
			flval[i]+=a[hang4][lie4];
		}
		flval[i]-=a[hang4][lie4];
	//	printf("current = %d\n",flval[i]);
		f[i].emplace_back(mkli(hang2,lie2,hang4,lie4));
        assert(flval[i]>=0);
	}
//	puts("???");
	int ans=0;
	FOR(i,1,n) {
		FOR(j,i+1,n) {
			ckmx(ans,flval[i]+flval[j]-un(i,j));
		//	printf("i = %d j = %d ans = %d %d f = %d\n",i,j,flval[i],flval[j],un(i,j));
		}
	}
	printf("%d\n",ans);
	return 0;
}
2024/4/2 12:56
加载中...