zoukankan      html  css  js  c++  java
  • NOJ 1072 The longest same color grid(尺取)

    Problem 1072: The longest same color grid

    Time Limits:  1000 MS   Memory Limits:  65536 KB

    64-bit interger IO format:  %lld   Java class name:  Main

    Description

    There are n grid, m kind of color. Grid number 1 to N, color number 1 to M. 
    The color of each grid is painted in one of the m colors. Now let you remove the Grid does not exceed K, get a new sequence.
    Ask you the same color and continuous length of the grid sequence is the length of the number?

    Input

    The first line of input T, T group data. (T <= 20)
    The next line of input three numbers n, m and k. (1 < n, m,k <= 10^5)
    The next line of input n number, indicating that the color of each grid. (1 <= a[i] <= m)

    Output

    For each group of data output the same color and continuous grid sequence length.

    Sample Input

    1
    10 2 2
    1 2 1 2 1 1 2 1 1 2

    Output for Sample Input

    5

    Hint

    For example we can delete the fourth position and the seventh position

    题意:给你一个连续的数字染色序列,你最多可以去掉k个格子使得某些格子变成连续的,比如样例的去掉第二和第四个格子,中间的便有5个1是连续的……

    学长出的题,刚看到真的是跪了,1e5的范围知道肯定不能两个for去暴力,想过尺取法,然而只是在原序列上进行尺取,这样并不知道到底删除[L,R]中哪几个点才能得到最大的连续长度。

    后来学长说是用vector数组记录每一种颜色所出现的下标,对每一种颜色的vector进行尺取,若设左右游标为L、R,则区间内的元素下标就是 $vector[color][Li……Ri]$,区间总长度(闭区间)为 $vector[color][R]-vector[color][L]+1$,所删除的块为记为 $cnt$个,则可获得 $vector[color][R]-vector[color][L]+1-cnt$,依次对每一个颜色的vector进行尺取更新答案即可

    代码:

    #include <stdio.h>
    #include <bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define CLR(arr,val) memset(arr,val,sizeof(arr))
    #define LC(x) (x<<1)
    #define RC(x) ((x<<1)+1)
    #define MID(x,y) ((x+y)>>1)
    typedef pair<int,int> pii;
    typedef long long LL;
    const double PI=acos(-1.0);
    const int N=1e5+7;
    int arr[N];
    vector<int>vec[N];
    
    void init(int m)
    {
        for (int i=0; i<=m; ++i)//这里写成 <m 又让我WA了一次,苦逼
            vec[i].clear();
    }
    int main(void)
    {
        int tcase,n,m,k,i,color;
        scanf("%d",&tcase);
        while (tcase--)
        {
            scanf("%d%d%d",&n,&m,&k);
            init(m);
            for (i=1; i<=n; ++i)
            {
                scanf("%d",&color);
                vec[color].push_back(i-1);
                //printf("%d<-%d
    ",color,i-1);
            }
            int ans=1;
            for (i=1; i<=m; ++i)
            {
                if(vec[i].empty())
                    continue;
                int L=0,R=0;
                int cnt=0;
                int SZ=vec[i].size();
                while (L<SZ)
                {
                    while (R<SZ)
                    {
                        ++R;
                        if(R>=SZ)
                        {
                            --R;
                            break;
                        }
                        //printf("[%d %d]
    ",vec[i][R-1],vec[i][R]);
                        cnt=cnt+vec[i][R]-vec[i][R-1]-1;
                        if(cnt>k)
                        {
                            cnt=cnt-(vec[i][R]-vec[i][R-1]-1);
                            --R;
                            break;
                        }
                    }
                    int now=vec[i][R]-vec[i][L]-cnt+1;
                    if(now>ans)
                        ans=now;
                    ++L;
                    if(L>=SZ)
                        break;
                    else
                        cnt=cnt-(vec[i][L]-vec[i][L-1]-1);
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    获取具体地址的经纬度
    git更换 拉取推送地址
    array_merge 优化调整
    重启电脑后,redis 6380端口关闭重启
    清空git默认的用户名和密码,
    对一个给定的二维数组按照指定的键值进行排序
    Vim编辑器-批量注释与反注释
    Linux信号处理
    Linux 进程间通信
    mkdir
  • 原文地址:https://www.cnblogs.com/Blackops/p/5988811.html
Copyright © 2011-2022 走看看