标题:日志统计

小明维护着一个程序员论坛。现在他收集了一份"点赞"日志,日志共有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\n",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;

    }

 

 

 

posted on 2019-02-28 20:22  可怕hiahia  阅读(125)  评论(0编辑  收藏  举报