• 寒假4



    标题:日志统计

    小明维护着一个程序员论坛。现在他收集了一份"点赞"日志,日志共有N行。其中每一行的格式是:

    ts id

    表示在ts时刻编号id的帖子收到一个"赞"。

    现在小明想统计有哪些帖子曾经是"热帖"。如果一个帖子曾在任意一个长度为D的时间段内收到不少于K个赞,小明就认为这个帖子曾是"热帖"。

    具体来说,如果存在某个时刻T满足该帖在[T, T+D)这段时间内(注意是左闭右开区间)收到不少于K个赞,该帖就曾是"热帖"。

    给定日志,请你帮助小明统计出所有曾是"热帖"的帖子编号。

    【输入格式】
    第一行包含三个整数N、D和K。
    以下N行每行一条日志,包含两个整数ts和id。

    对于50%的数据,1 <= K <= N <= 1000
    对于100%的数据,1 <= K <= N <= 100000 0 <= ts <= 100000 0 <= id <= 100000

    【输出格式】
    按从小到大的顺序输出热帖id。每个id一行。

    【输入样例】
    7 10 2
    0 1
    0 10
    10 10
    10 1
    9 1
    100 3
    100 3

    【输出样例】
    1
    3

    这个题要用到尺取法。

    关于“尺取法”,我的理解:

    (1)涉及“(寻找任一个)区间”。

    (2)想清楚两个点:①针对题意,怎么找到这个区间,即这个区间应满足怎样的条件。②关于start和end标识,什么时候start++,什么时候end++,什么时候应该跳出循环。anyway,要好好分析题意,结合题意设计。

    #include<iostream>
    #include<bits/stdc++.h>
    using namespace std;
    int n,d,k;
    vector<int>v[100005];
    set<int>ans;
    bool judge(int id)
    {
        int cnt=0;
        int len=v[id].size();
        if(len<k)
            return 0;
        int start=0,end=0;
        sort(v[id].begin(),v[id].end());
        while(start<=end&&end<len)
        {
            cnt++;
            if(cnt>=k)
            {
                if(v[id][end]-v[id][start]<d)
                {
                    return 1;
                }
                else
                {
                    cnt--;
                    start++;
                }
    
            }
            end++;
        }
        return 0;
    }
    int main()
    {
        int ts,id;
        cin>>n>>d>>k;
        while(n--)
        {
            cin>>ts>>id;
            v[id].push_back(ts);
        }
        for(int i=1;i<=1010;i++)
        {
            if(judge(i))
            {
                ans.insert(i);
            }
        }
        set<int>::iterator it;
        for(it=ans.begin();it!=ans.end();it++)
        {
            cout<<*it<<endl;
        }
        return 0;
    
    }

    标题:全球变暖

    你有一张某海域NxN像素的照片,"."表示海洋、"#"表示陆地,如下所示:

    .......
    .##....
    .##....
    ....##.
    ..####.
    ...###.
    .......

    其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。

    由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。

    例如上图中的海域未来会变成如下样子:

    .......
    .......
    .......
    .......
    ....#..
    .......
    .......

    请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。

    【输入格式】
    第一行包含一个整数N。 (1 <= N <= 1000)
    以下N行N列代表一张海域照片。

    照片保证第1行、第1列、第N行、第N列的像素都是海洋。

    【输出格式】
    一个整数表示答案。

    【输入样例】
    7
    .......
    .##....
    .##....
    ....##.
    ..####.
    ...###.
    .......

    【输出样例】
    1

    一个dfs判断

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int mp[110][110];
    int ans[11000];
    bool vis[110][110];
    void dfs(int x,int y,int k)
    {
        if(mp[x][y]=='.')
            return;
        if(vis[x][y])
            return;
        vis[x][y]=1;
        if(mp[x-1][y]=='#'&&mp[x+1][y]=='#'&&mp[x][y-1]=='#'&&mp[x][y+1]=='#')
            ans[k]++;
        dfs(x+1,y,k);
        dfs(x-1,y,k);
        dfs(x,y-1,k);
        dfs(x,y+1,k);
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            getchar();
            for(int j=1;j<=n;j++)
                scanf("%c",&mp[i][j]);
    
        }
        int len=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(mp[i][j]=='#'&&!vis[i][j])
                {
                    dfs(i,j,len);
                    len++;
                }
            }
        }
        int sum=0;
        for(int i=0;i<len;i++)
            if(ans[i]==0)
                sum++;
        printf("%d
    ",sum);
    }
    L2-026 小字辈 (25 分)

    本题给定一个庞大家族的家谱,要请你给出最小一辈的名单。

    输入格式:

    输入在第一行给出家族人口总数 N(不超过 100 000 的正整数) —— 简单起见,我们把家族成员从 1 到 N 编号。随后第二行给出 N 个编号,其中第 i 个编号对应第 i 位成员的父/母。家谱中辈分最高的老祖宗对应的父/母编号为 -1。一行中的数字间以空格分隔。

    输出格式:

    首先输出最小的辈分(老祖宗的辈分为 1,以下逐级递增)。然后在第二行按递增顺序输出辈分最小的成员的编号。编号间以一个空格分隔,行首尾不得有多余空格。

    输入样例:

    9
    2 6 5 5 -1 5 6 4 7
    

    输出样例:

    4
    1 9
    用到了树和递归思想
    #include<iostream>
    #include<cstdio>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    using namespace std;
    int f[1000001],a[1000001];
    int find(int x)
    {
        if(a[x])
            return a[x];
        else if(f[x]==-1)
            return a[x]=1;
        else
            return a[x]=find(f[x])+1;
    }
    int main()
    {
        int n,i;
        cin>>n;
        for(i=1;i<=n;i++)
        {
            cin>>f[i];
        }
        int max=0;
        for(i=1;i<=n;i++)
        {
            if(find(i)>max)
                max=find(i);
        }
        cout<<max<<endl;
        int flag=1;
        for(i=1;i<=n;i++)
        {
            if(a[i]==max)
            {
                 if(flag==0)
                cout<<" ";
               cout<<i;
               flag=0;
            }
        }
        return 0;
    
        }
     
  • 相关阅读:
    Windows 操作系统引导过程 BIOS & EFI
    Mac 系统引导过程概述 & BootCamp 的秘密
    Windows 10 安装 Ubuntu 子系统
    nrm 安装及报错处理
    司马懿人物关系
    大江大河
    曹操人物关系
    必要条件探路(导数)
    该题七种想法(一题一课之外接球)
    欧拉-查柏(Euler-Chapple)公式及其推广
  • 原文地址:https://www.cnblogs.com/kepa/p/10452878.html
Copyright © 2020-2023  润新知