Codeforces Round #401 (Div. 2)(C,D,E)

CN_swords發表於2017-02-25

/*
C. Alyona and Spreadsheet
時間: 2017/02/25
題意:給出q個詢問,問第l行到第r行是否存在一列是非單調遞減的。
題解:
建一個陣列:f[i] 代表i行最多能非單調遞減到達的行數
對於每列不斷更新這個陣列即可,
*/

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
#define LL long long
#define N 100010
#define INF 0x3f3f3f3f

int a[N],f[N];
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i = 1; i <= n*m ; i++)
            scanf("%d",&a[i]);
        int k;
        for(int i = 1; i <= m; i++)
        {
            for(int j = 1; j <= n; j = k)
            {
                for(k = j+1; k <= n ; k++)
                    if(a[(k-2)*m+i] > a[(k-1)*m+i])
                        break;
                for(int p = j; p < k; p++)
                        f[p] = max(f[p],k-1);
            }
        }
        int q;
        scanf("%d",&q);
        int l,r;
        while(q--)
        {
            scanf("%d%d",&l,&r);
            if(f[l] >= r)
                puts("Yes");
            else
                puts("No");
        }
    }
    return 0;
}



/*
D. Cloud of Hashtags
時間: 2017/02/25
題意:刪去最少的字元,使其滿足字典序排序
題解:這題我以為會爆遲遲不敢動手,
明顯需要從後往前推,記錄其刪去到的字元長度比較方便。
*/


#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
#define LL long long
#define N 500010
#define INF 0x3f3f3f3f

string s[N];
int l[N];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i = 0; i < n; i++)
        {
            cin >> s[i];
            l[i] = s[i].size();
        }
        for(int i = n-2; i >= 0; i--)
        {
            int len = min(l[i],l[i+1]);
            int flag = 0;
            int j;
            for(j = 0; j < len; j++)
            {
                if(s[i][j] > s[i+1][j])
                {
                    l[i] = j;
                    break;
                }
                else if(s[i][j] < s[i+1][j])
                {
                    flag = 1;
                    break;
                }
            }
            if(!flag && j == len)   l[i] = len;
        }
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < l[i]; j++)
                printf("%c",s[i][j]);
            puts("");
        }
    }
    return 0;
}



/*
E. Hanoi Factory
時間: 2017/02/25
題意:疊塔,但要滿足a(i+1) < bi <= b(i+1)
題解:
標程是線段樹+LIS
群裡說貪心也能做,排序b從小到大,在b相同排序a從小到大,使其滿足如果i-1不能取,那麼i-2也不能取,
這樣從後往前推入棧,如果不滿足推出棧直到滿足再推入棧,每次推入的答案記錄最大值即可。
*/


#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
using namespace std;
#define LL long long
#define N 100010
#define INF 0x3f3f3f3f

struct point
{
    int x,y,h;
} a[N];
bool cmp(point a,point b)
{
    if(a.y != b.y) return a.y < b.y;
    return a.x < b.x;
}
int dp[N];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i = 0; i < n; i++)
            scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].h);
        sort(a,a+n,cmp);
        stack<point> p;
        LL ans = 0;
        LL mx = 0;
        for(int i = n-1; i >= 0; i--)
        {
            while(1)
            {
                if(p.empty())
                    break;
                point f = p.top();
                if(f.y >= a[i].y && f.x < a[i].y)
                    break;
                ans -= f.h;
                p.pop();
            }
            p.push(a[i]);
            ans += a[i].h;
            mx = max(mx,ans);
        }
        printf("%I64d\n",mx);
    }
    return 0;
}


相關文章