题解:SP6517 JOCHEF - Farmer Sepp
一眼简单悬线法,而且有多倍经验,感觉这题被遗忘了,那我就拿下这个水紫吧!
我们用 a 数组表示能向上延伸能到达的最大距离,依次遍历每一行,如果该位置为 F,他可以从上一行转移过来,将a数组增加一,如果该位置为 C,意味着这个位置不能成矩形,将 a 数组变为 0。
接下来进行悬线法的标准操作,设 l 数组为能向左延伸到不低于此位置的高度的最远位置,然后进行推导。
-
当 \(i=1\),到达边界停止。
-
当 \(a[i]>a[i-1]\),低于高度,停止拓展。
-
当 \(a[i]<=a[i-1]\),可以扩展,直接继承 \(l[i]=l[l[i]-1]\)。
r 数组则是向右延伸,相同方法赋值即可,最后统计答案直接将高度乘上可延伸的长度,结果取最大值一气呵成。
运行过程类似下图(其他题的图片但同一个意思)。
注意这题有多组数据,换行与多测清空都要注意。
上代码!!!
#include <bits/stdc++.h> #define ll long long using namespace std; const int N=1e4+10; #define int ll int n,m,k; int a[N]; int l[N],r[N]; int ans; signed main(){ ios::sync_with_stdio(false); cin.tie(nullptr); while(1){ cin>>n>>m; if(n==m&&n==0){ break; } ans=0; memset(a,0,sizeof a); cin>>k; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ l[j]=r[j]=j; } char c; for(int j=1;j<=m;j++){ cin>>c; if(c=='C'){ a[j]=0; } else if(c=='H'){ a[j]++; } } for(int j=1;j<=m;j++){ while(l[j]!=1&&a[j]<=a[l[j]-1]){ l[j]=l[l[j]-1]; } } for(int j=m;j>=1;j--){ while(r[j]!=m&&a[j]<=a[r[j]+1]){ r[j]=r[r[j]+1]; } } for(int j=1;j<=m;j++){ ans=max(ans,a[j]*(r[j]-l[j]+1)); } } cout<<(ll)ans*k<<"\n"; } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」