zoukankan      html  css  js  c++  java
  • P2058 海港

    原题链接  https://www.luogu.org/problemnew/show/P2058

    这道题昨天qyf大佬刚给我们讲了一下,所以今天就把它做啦!

    qyf大佬的思路和我的是一样的(其实是借鉴了qyf大佬的思路),但是由于他是用的指针+动态数组来实现的,这搞得我有些懵,今天仔细一想(没看题解QwQ~)发现可以用队列来实现,所以为了记录这个思路,写了一篇队列的博客。

    想看指针+动态数组实现的同学们戳这里,还送屠龙宝刀哦~  传送门

    首先这是一道模拟题,思路也很简单:

    1. 题目中要求有多少个不同的国籍,所以我们先开一个 nat 数组类似于桶排那样来记录第 i 个国籍有多少人;

    2. 对于当前到来的船,我们可以将这艘船的所有乘客全入队(注意是乘客!),他们维护两个信息:到来的时间 t 和国籍 nation;

    3. 我们要统计 ( t- 86400,ti ] ,所以我们要有一个 delete 操作将队列里所有 t <= ti - 86400 的乘客弹出队列,同时注意对应的国籍人数减一;

    4. 考虑到 nat 记录的是国籍的人数,那么我们可以想到:若 nat [ i ] 从一个大于0的数减到了0,那么不就说明这个国籍就没有了?此时的国籍数kind就要 -1;同理若 nat [ i ] 从0加了一个正数,说明该国籍出现了,那么此时的国籍数kind 就要 +1;

    5. 然后我们输出kind 即可;

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    int read()
    {
        char ch=getchar();
        int a=0,x=1;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-') x=-x;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            a=(a<<3)+(a<<1)+(ch-'0');
            ch=getchar();
        }
        return a*x;
    }
    struct people
    {
        int t,nation;
    }a[100001];
    queue<people> q;
    int n,num,guo,kind,t[100001],vis[100001];
    void delet(int tim)
    {
        people f=q.front();               //因为我们是按照时间顺序来将乘客入队的,所以队首乘客的t一定最小 
        while(f.t<=tim)
        {
            q.pop();
            vis[f.nation]--;              //对应国籍人数减一 
            if(vis[f.nation]==0) kind--;  //国籍人数减到0,说明这种国籍消失,国籍数kind减一    
            f=q.front();
        }
        return ;
    }
    int main()
    {
        n=read();                         //n艘船 
        for(int i=1;i<=n;i++)
        {
            t[i]=read();                  //这一艘船到来的时间 
            num=read();                   //乘客人数  
            for(int j=1;j<=num;j++) 
            {
                guo=read();               //所属国籍 
                if(!vis[guo]) kind++;     //如果之前这种国籍的人数为0,说明多了一种国籍 
                vis[guo]++;
                q.push((people){t[i],guo});//入队,维护时间t 和国籍nation 
            }
            delet(t[i]-86400);            //删除t[i]-86400以前的船,注意要放在入队操作之后 
            printf("%d
    ",kind);          
        }
        return 0;
    }
  • 相关阅读:
    游戏编程模式之事件队列模式
    游戏编程模式之组件模式
    游戏编程模式之类型对象模式
    游戏编程模式之父类沙盒模式
    游戏编程模式之字节码模式
    游戏人工智能简介
    游戏编程模式之更新模式
    游戏编程模式之游戏循环
    .vimrc配置文件 + gvim 运行 gnome-terminal 完成后等待
    js 批量移除steam游戏 移除用户凭证中免费获取的物品
  • 原文地址:https://www.cnblogs.com/xcg123/p/11097748.html
Copyright © 2011-2022 走看看