题目链接:http://acm.whu.edu.cn/land/problem/detail?problem_id=1567&contest_id=14
题意:给定连续行的高度,把每个行看成二维,每次用矩形划分行中的一块,问最少划分几次
思路:类似以前做过的一个最大矩形面积题。找到一行的left,即h[left]>=h[i],h[left-1]<h[i]的点,注意一下边界处理。然后排序,从小到大,先按高度,再按left。若某点的高度和left均与前一点相同,则continue,否则ans++
错误点是本题多组数据没用while(scanf())我也是醉了.....
源码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int const MAXN = 1000+100;
struct D
{
int l;
int h;
}d[MAXN];
int n;
//int l[MAXN],r[MAXN],n,tl[MAXN];
//ll h[MAXN],th[MAXN];
void init()
{
int i,j;
int last,pre;
d[0].l = 0;
// for(i=0; i<n; i++)
// printf("%d ",d[i].h);
// printf("\n");
for(i=1; i<n; i++){
pre = i-1;
while(pre>=0){
if(d[pre].h>=d[i].h){
pre = d[pre].l-1;
}
else
break;
}
d[i].l = pre+1;
}
// for(i=0; i<n; i++)
// printf("%d ",d[i].l );
// printf("\n");
}
bool cmp(D a,D b)
{
// if(th[a]!=th[b])
// return th[a]<th[b];
// else
// return tl[a]<tl[b];
if(a.h != b.h)
return a.h<b.h;
return a.l<b.l;
}
void solve()
{
int ans = 1;
// memcpy(th,h,sizeof h);
// memcpy(tl,l,sizeof l);
// sort(l,l+n,cmp);
// sort(h,h+n,cmp);
sort(d,d+n,cmp);
for(int i=1; i<n; i++){
if(d[i].h==d[i-1].h && d[i].l==d[i-1].l)
continue;
ans++;
}
// printf("\nh = \n");
// for(int i=0; i<n; i++)
// printf("%d ",d[i].h);
// printf("\nl = \n");
// for(int i=0; i<n; i++)
// printf("%d ",d[i].l);
// printf("\n");
printf("%d\n",ans);
}
//void check()
//{
// printf("\nleft\n");
// for(int i=0; i<n; i++)
// printf("%d ",l[i]);
// printf("\nright\n");
// for(int i=0; i<n; i++)
// printf("%d ",r[i]);
// printf("\n");
//}
int main()
{
while(scanf("%d",&n)!=EOF){
int i,j,k;
for(i=0; i<n; i++){
scanf("%d",&d[i].h);
// printf("\nd[%d] = %d",i,d[i].h);
}
init();
// check();
solve();
}
return 0;
}