hdu 1505&1506&2870&2830

来源:互联网 发布:广东网络干部学院 编辑:程序博客网 时间:2024/06/11 03:04

1506

呃..题目虽基础,但这个思路挺好,利用栈找出一个区间的左右边界,也就是区间的范围,在这儿记录一下免得以后忘了,还要吐槽下hdu数据不科学..

这个思路还能解另一道题,明天敲一下。

//原理: 利用栈构造一个非减的序列,一个元素进栈时l[i]则确定了,出栈时r[i]则确定了
#include<cstdio>#include<cstring>#include<algorithm>#include<stack>using namespace std;#define maxn 100005long 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。。。