zoukankan      html  css  js  c++  java
  • Gym

    题目:

    To encourage visitors active movement among the attractions, a circular path with ice cream stands was built in the park some time ago. A discount system common for all stands was also introduced. When a customer buys ice cream at some stand, he is automatically granted a discount for one day at the next stand on the path. When visitors start at any stand and follow systematically the discount directions to the next stands, they eventually traverse the whole circular path and return back to the stand they started at.

    Ice creams of various brands are sold at the stands. Additionally, each stand sells a nice sample box which contains small samples of popular ice cream brands. The number of samples in the box depends on the stand and various stands may put different brands into their sample boxes. Each box contains samples of one or more brands. A brand may be represented by one or more samples in the box, or it may be completely missing. Each stand sells only one type of sample box (the brands of the samples in the box are always the same for that particular stand).

    Quido and Hugo are going to exploit the discount system for their own benefit. They decided to start at some stand and then continue in the direction of the discounts buying one ice cream sample box at each stand they visit in a consecutive sequence. Their goal is to collect at least one sample of each ice cream brand sold in the park. Simultaneously, to respect their stomach capacities, they want to minimize the total number of ice cream samples they buy.

    Input Specification:

    There are more test cases. Each case starts with a line containing two integers N, K separated by space (1 ≤ N, K ≤ 106 ). N is the number of ice cream stands, K is the total number of different ice cream brands sold at all stands. The brands are labeled by numbers 1, 2, . . . , K. Next, there are N lines describing stands in their visiting order. Each such line contains the list of brands of all ice cream samples sold in the sample box at that particular stand. Each list starts with one positive integer L, describing its length, followed by L integers. Each list item represents the brand of one ice cream sample in the sample box sold at this stand. You may assume that even if a visitor buys one sample box at each stand, he/she will collect at most 107 ice cream samples.

    Output Specification:

    For each test case, print a single line with one integer denoting the minimum number of ice cream samples Quido and Hugo have to buy in order to obtain a sample of each ice cream brand sold in the park. If it is impossible to obtain samples of all brands output −1.

    题意:

    这题的题意太难懂了,还是英语水平不够啊。抽象出来的题意是在给出的样例中找一个连续的区间,使得这个区间中的数包含1,2,3...,k这些数,而且数的个数要求最小。

    思路:

    是一个环,所以先将序列加倍,然后利用尺取法。

    举个例子:N==3,K==3

    1 1

    1 2

    3 1 2 3

    尺取法做的时候第一次从左到右,1,2,3连在一起才是符合条件的,但是单独一个3也是符合条件的,而且数的个数更小。

    所以这里就要注意:当得到一个符合条件的值的时候,我们让他的起点加一,直到不符合条件的情况出现,这个时候终点继续加一往后枚举。

    之前做的尺取法都是遇到符合条件的情况后直接令起点等于终点继续枚举,思路还是没有拓展开。

    代码:

    #include <bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define FRE() freopen("in.txt","r",stdin)
    using namespace std;
    typedef long long ll;
    const int maxn = 1e6+10;
    int vis[maxn];
    int N,K,ans;
    vector<int> v[maxn*2];
    int main(){
        //FRE();
        while(scanf("%d%d",&N,&K)!=EOF){
            for(int i = 0; i<maxn*2; i++){
                v[i].clear();
            }
            memset(vis,0,sizeof(vis));
            for(int i = 0; i<N; i++){
                int t,a;
                scanf("%d",&t);
                for(int j = 0; j<t; j++){
                    scanf("%d",&a);
                    v[i].push_back(a);
                    v[i+N].push_back(a);//数组加倍
                }
            }
            ans = 1e8;
            int st = 0,en = 0;
            int k = 0,res = 0;
            while(en <= 2*N){
                res += v[en].size();
                for(int i = 0; i<v[en].size(); i++){
                    int index = v[en][i];
                    if(vis[index] == 0){
                        k++;
                    }
                    vis[index]++;
                }
                while(k==K && st<=en){//起点加一,直到不符合条件的情况出现
                    ans = min(ans, res);
                    res -= v[st].size();
                    for(int i = 0; i<v[st].size(); i++){
                        int index = v[st][i];
                        vis[index]--;
                        if(vis[index] == 0){
                            k--;
                        }
                    }
                    st++;
                }
                en++;
            }
            if(ans==1e8){
                printf("-1
    ");
            }
            else
                printf("%d
    ",ans);
        }
        return 0;
    }
    /*
    PutIn:
    4 3
    4 1 3 1 3
    1 2
    2 3 3
    1 1
    5 3
    1 2
    1 3
    2 1 1
    2 2 2
    1 1
    3 2
    2 1 1
    1 1
    3 1 1 1
    PutOut:
    4
    3
    -1
    */
    View Code
  • 相关阅读:
    【SQLServer】 查询一个字段里不同值的最新一条记录
    【MySQL】mysql5.7数据库的安装和配置
    【Java】JDK安装及环境变量配置
    【Oracle】SQL语句优化
    【JavaScript】 控制自适应高度
    【Java】登录验证码
    【JavaScript】 直接下载保存文件
    【Java】Java批量文件打包下载zip
    【Java】Java 单文件下载及重命名
    主机在无线网络的情况下,设置centos7.2虚拟机网络联通
  • 原文地址:https://www.cnblogs.com/sykline/p/9878542.html
Copyright © 2011-2022 走看看