您的位置:首页 > 其它

Codeforces 527 C Glass Carving----瞎搞

2015-05-11 18:16 281 查看
题目链接点击打开链接

题意:对一个w*h的矩形,横向或者纵向切割(切割点是整数)。每次输入横向或纵向切割的点,求每一次切割后面积最大的块。

思路:切割点把边长分成若干块,我们只需知道每一次切割后最长的横向段和纵向段,结果就是两者之积。最容易想到的,就是每次扫一遍求两个最大值,然而由于数据量太大n*n的方法肯定会T。改进一下方法,因为需要动态改变被切割边长度,所以用set存所有的段的结果,而set查询最大值的时间复杂度是log(n),可以承受。

PS:在cf上看到还有人用线段树的方法动态更新查找,回头也搞一发。

话说用cin cout会T是什么鬼。cf对于c++的优化不是很强大的么╮(╯_╰)╭

AC代码:

#include <cstdio>
#include <bits/stdc++.h>
#include<cmath>
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
#define debug puts("xxxxxxx")
#define pi (acos(-1.0))
#define eps (1e-8)
#define inf 0x3f3f3f3f
typedef long long ll;
using namespace std;
set<int> x,y;///存哪些点被切割
int vx[200006],vy[200006];///被切割长度的个数
set<int>mx,my;///被切割长度得集合
set<int> :: iterator it1,it2;
void gao( set<int> & t1, set<int> &t2 ,int *v,int x)///t1 代表x,y  t2表示mx,my
{
    if(!t1.count(x))
    {
        it1 = t1.lower_bound(x);
        it2 = it1,it1--;
        int l = *it2-*it1;
        v[l]--;
        if(v[l]==0) t2.erase(l);
        t2.insert(*it2-x),v[*it2-x]++;
        t2.insert(x-*it1),v[x-*it1]++;
        t1.insert(x);
    }
}
int main()
{
    int w,h,n,t;
    std::ios_base::sync_with_stdio(false);
    memset(vx,0,sizeof(vx));
    memset(vy,0,sizeof(vy));
    char c;
    cin>>w>>h>>n;
    x.insert(w),y.insert(h);
    x.insert(0),y.insert(0);
    mx.insert(w),my.insert(h);
    vx[w]++,vy[h]++;
    while(n--)
    {
        cin>>c>>t;
        if(c=='V') gao(x,mx,vx,t);
        else gao(y,my,vy,t);
        it1 = mx.end(),it2 = my.end();
        it1--,it2--;
        ll x1 = (*it1)*1ll,x2=(*it2)*1ll;
        ll ans = x1*x2;
        cout<<ans<<endl;
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: