1506
呃..题目虽基础,但这个思路挺好,利用栈找出一个区间的左右边界,也就是区间的范围,在这儿记录一下免得以后忘了,还要吐槽下hdu数据不科学..
这个思路还能解另一道题,明天敲一下。
//原理: 利用栈构造一个非减的序列,一个元素进栈时l[i]则确定了,出栈时r[i]则确定了
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
using namespace std;
#define maxn 100005
long long l[maxn],r[maxn],h[maxn];
stack<int> S;
long long n;
int main()
{
int i;
long long ans,tmp;
while(scanf("%I64d",&n)&&n)
{
for(i=1;i<=n;++i)
scanf("%I64d",h+i);
while(!S.empty())
S.pop();
ans=0;
l[1]=0;
S.push(1);
for(i=2;i<=n;++i)
{
while(!S.empty()&&(h[i]<h[S.top()]))
{
r[S.top()]=i;
S.pop();
}
if(S.empty())
l[i]=0;
else if(h[i]==h[S.top()])
l[i]=l[S.top()];
else
l[i]=S.top();
S.push(i);
}
while(!S.empty())
{
r[S.top()]=n+1;
S.pop();
}
for(i=1;i<=n;++i)
{
tmp=h[i]*(r[i]-l[i]-1);
if(tmp>ans)
ans=tmp;
}
printf("%I64d\n",ans);
}
}
1505是1506的加强版,注意字符输入,scanf("%c")不能过滤空格,用cin吧,思路:枚举行数,对于每一行按照1506的做法求一个最大面积,2870是1505的加强版,改天再做,明天早上近代史考试求RP!
#include<iostream>
#include<cstdio>
#include<stack>
#include<cstring>
#include<algorithm>
#include<fstream>
using namespace std;
char map[1005][1005];
int h[1005];
int n,m;
int maxarea()
{
stack<int> s;
int l[1005],r[1005],ans=0,t,i;
l[1]=0;
s.push(1);
for(i=2;i<=m;++i)
{
while(!s.empty()&&h[i]<h[s.top()])
{
r[s.top()]=i;
s.pop();
}
if(s.empty())
l[i]=0;
else if(h[i]==h[s.top()])
l[i]=l[s.top()];
else
l[i]=s.top();
s.push(i);
}
while(!s.empty())
r[s.top()]=m+1,s.pop();
for(i=1;i<=m;++i)
{
t=h[i]*(r[i]-l[i]-1);
if(t>ans)
ans=t;
}
return ans;
}
int main()
{
int K,i,j,ans,t;
// ifstream fin;
// fin.open("data.txt");
// scanf("%d",&K);
// fin>>K;
cin>>K;
while(K--)
{
// scanf("%d %d",&n,&m);
// fin>>n>>m;
cin>>n>>m;
for(i=0;i<n;++i)
{
getchar();
for(j=0;j<m;++j)
cin>>map[i][j];
// fin>>map[i][j];
}
memset(h,0,sizeof(h));
ans=0;
for(i=0;i<n;++i)
{
for(j=0;j<m;++j)
{
if(map[i][j]=='F')
h[j+1]+=1;
else
h[j+1]=0;
}
t=maxarea();
if(t>ans)
ans=t;
}
printf("%d\n",ans*3);
}
// system("pause");
return 0;
}
2870又是1505的加强版,这里有a,b,c,w,x,y,z 7种字符构成的矩形,求由a,b,c中同一种字符组成的最大矩形面积,其中w可当作a,b x b,c y a,c z a,b,c,方法就是枚举求出a,b,c各自的最大矩形面积然后求最大值就行了 ps:初始化写成了memset(h,0,sizeof(0))编译器竟然没提示错误,害我找了半天错误...
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<fstream>
#include<stack>
using namespace std;
stack<int> s;
int n,m;
char map[1005][1005];
int l[1005],r[1005],h[1005];
bool available(char p,char t)
{
if(p=='a')
{
if(t=='a'||t=='w'||t=='y'||t=='z')
return 1;
else
return 0;
}
else if(p=='b')
{
if(t=='b'||t=='w'||t=='x'||t=='z')
return 1;
else
return 0;
}
else
{
if(t=='c'||t=='x'||t=='y'||t=='z')
return 1;
else
return 0;
}
}
int maxarea(char c)
{
int i,j,t,ans=0;
while(!s.empty())
s.pop();
memset(h,0,sizeof(h));
for(i=1;i<=n;++i)
{
memset(l,0,sizeof(l));
// cout<<"h ";
for(j=1;j<=m;++j)
{
if(available(c,map[i-1][j-1]))
h[j]++;
else
h[j]=0;
// cout<<h[j]<<" ";
}
// cout<<endl;
s.push(1);
for(j=2;j<=m;++j)
{
while(!s.empty()&&h[s.top()]>h[j])
{
r[s.top()]=j;
s.pop();
}
if(!s.empty())
{
if(h[s.top()]==h[j])
l[j]=l[s.top()];
else
l[j]=s.top();
}
s.push(j);
}
while(!s.empty())
{
r[s.top()]=m+1;
s.pop();
}
// cout<<"l ";
// for(j=1;j<=m;++j)
// cout<<l[j]<<" ";
// cout<<endl;
// cout<<"r ";
// for(j=1;j<=m;++j)
// cout<<r[j]<<" ";
// cout<<endl;
for(j=1;j<=m;++j)
if((t=h[j]*(r[j]-l[j]-1))>ans)
ans=t;
}
// cout<<ans<<endl;
return ans;
}
int main()
{
int i,j,ans;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(i=0;i<n;++i)
{
getchar();
for(j=0;j<m;++j)
scanf("%c",&map[i][j]);
}
ans=max(maxarea('a'),max(maxarea('b'),maxarea('c')));
printf("%d\n",ans);
}
return 0;
}
2830 还是求最大面积,但是这题的任意两列都可以交换,这样只要排序后就找到l和r了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m;
int h[1005],t[1005];
char map[1005][1005];
int maxarea()
{
int i,j,tmp,ans=0;
for(i=0;i<m;++i)
t[i]=h[i];
sort(t,t+m);
for(i=0;i<m;++i)
{
tmp=t[i]*(m-i);
if(tmp>ans)
ans=tmp;
}
return ans;
}
int main()
{
int i,j,ans,tmp;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(i=0;i<n;++i)
{
getchar();
for(j=0;j<m;++j)
scanf("%c",&map[i][j]);
}
memset(h,0,sizeof(h));
ans=0;
for(i=0;i<n;++i)
{
for(j=0;j<m;++j)
if(map[i][j]=='1')
h[j]++;
else
h[j]=0;
tmp=maxarea();
if(tmp>ans)
ans=tmp;
}
printf("%d\n",ans);
}
return 0;
}
还有一题,to be continued。。。