【2016福建省夏令营Day1】数据结构

Problem 1 楼房(build.cpp/c/pas)

【题目描述】

地平线(x轴)上有n个矩(lou)形(fang),用三个整数h[i],l[i],r[i]来表示第i个矩形:矩形左下角为(l[i],0),右上角为(r[i],h[i])。地平线高度为0。在轮廓线长度最小的前提下,从左到右输出轮廓线。

下图为样例2。

【输入格式】

第一行一个整数n,表示矩形个数。

以下n行,每行3个整数h[i],l[i],r[i]表示第i个矩形。

【输出格式】

第一行一个整数m,表示节点个数。

以下m行,每行一个坐标表示轮廓线上的节点。从左到右遍历轮廓线并顺序输出节点。第一个和最后一个节点的y坐标必然为0。

【样例输入】

2
3 0 2
4 1 3

【样例输出】

6
0 0
0 3
1 3
1 4
3 4
3 0

【样例输入2】

5
3 -3 0
2 -1 1
4 2 4
2 3 7
3 6 8

【样例输出2】

14
-3 0
-3 3
0 3
0 2
1 2
1 0
2 0
2 4
4 4
4 2
6 2
6 3
8 3
8 0

【数据范围】

对于30%的数据,n<=100

对于另外30%的数据,n<=100000,1<=h[i],l[i],r[i]<=1000

对于100%的数据,1<=n<=100000,1<=h[i]<=10^9,-10^9<=l[i]<r[i]<=10^9

题解

扫描线+堆维护

推荐使用multset和pair 很方便

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;

pair<int,int> a[1000005],ans[1000005];
multiset<int> q;
int n,cnt,maxh,num;

int main()
{
    int i,j,h,x,y;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d%d%d",&h,&x,&y);
        a[++cnt]=make_pair(x,h);
        a[++cnt]=make_pair(y,-h);
    }
    sort(a+1,a+1+cnt);
    q.insert(0);
    maxh=0;
    for(i=1;i<=cnt;)
    {
        for(j=i;j<=cnt;j++)
        {
            if(a[i].first<a[j].first) break;
            else
             if(a[j].second>0) q.insert(a[j].second);
             else q.erase(q.find(-a[j].second));
        }
        h=*q.rbegin();
        if(h!=maxh)
        {
            ans[++num]=make_pair(a[i].first,maxh);
            ans[++num]=make_pair(a[i].first,h);
            maxh=h;
        }
        i=j;
    }
    printf("%d\n",num);
    for(i=1;i<=num;i++) printf("%d %d\n",ans[i].first,ans[i].second);
    return 0;
}

Problem 2 单词背诵(word.cpp/c/pas)

【题目描述】

灵梦有n个单词想要背,但她想通过一篇文章中的一段来记住这些单词。

文章由m个单词构成,她想在文章中找出连续的一段,其中包含最多的她想要背的单词(重复的只算一个)。并且在背诵的单词量尽量多的情况下,还要使选出的文章段落尽量短,这样她就可以用尽量短的时间学习尽可能多的单词了。

【输入格式】

第一行一个数n,表示想要背的单词数。

接下来n行每行是一个长度不超过10的字符串,表示一个要背的单词。

接着是一个数m,表示文章中的单词数

然后是m行长度不超过10的字符串,每个表示文章中的一个单词。

【输出格式】

输出文件共2行。第1行为文章中最多包含的要背的单词数,第2行表示在文章中包含最多要背单词的最短的连续段的长度。

【样例输入】

3

hot

dog

milk

5

hot

dog

dog

milk

hot

【样例输出】

3

3

【数据范围】

对于30%的数据 n<=50,m<=500;

对于60%的数据 n<=300,m<=5000;

对于100%的数据 n<=1000,m<=100000;

题解

哈希+双指针扫描

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define mod 233327
using namespace std;

int n,m,anscnt,ans,cnt;
char s[15],str[100005][15];
struct hh
{
    char v[15];
    int next;
};
hh e[5005];
int last[500005],hash[500005],vis[500005];
bool h[500005];
void insert(int x)
{
    ++cnt;
    strcpy(e[cnt].v,s);
    e[cnt].next=last[x];
    last[x]=cnt;
}

bool query(int x,int k)
{
    int i;
    for(i=last[x];i;i=e[i].next)
     if(!strcmp(e[i].v,str[k])) return true;
    return false;
}

int main()
{
    int i,j,len,thash,head,tail,now,tlen;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("\n%s",&s);
        len=strlen(s);thash=0;
        for(j=0;j<=len-1;j++)
          thash=(thash*233+s[j])%mod;
        insert(thash);
    }
    scanf("%d",&m);
    for(i=1;i<=m;i++)
    {
        scanf("\n%s",&str[i]);
        len=strlen(str[i]);thash=0;
        for(j=0;j<=len-1;j++)
         thash=(thash*233+str[i][j])%mod;
        hash[i]=thash;
    }
    for(i=1;i<=m;i++)
      if(query(hash[i],i)&&!h[hash[i]])
      {
          anscnt++;
          h[hash[i]]=true;
      }
    printf("%d\n",anscnt);

    if(!anscnt) goto hhh;
    head=1;tail=1;now=tlen=0;
    ans=100005;
    if(query(hash[1],1))
    {
        vis[hash[1]]=1;
        now++;
    }
    while((head<=tail&&tail<m)||now==anscnt)
    {
        if(now==anscnt)
        {
            ans=min(ans,tail-head+1);
            thash=hash[head++];
            if(query(thash,head-1))
            {
                vis[thash]--;
                if(!vis[thash]) now--;
            }
        }
        else
        {
            thash=hash[++tail];
            if(query(thash,tail))
            {
                if(!vis[thash]) now++;
                vis[thash]++;
            }
        }
    }
    hhh:;
    printf("%d",ans);
    return 0;
}

Problem 3 矩阵(matrix.cpp/c/pas)

【题目描述】

给定一个N行M列的非负整数矩阵,求一个最大的正方形子矩阵,该矩阵满足:

矩阵中每一个元素权值都大于0;

在满足上述条件的前提下,矩阵面积最大;

在满足上述条件的前提下,选择元素和最小的。

【输入格式】

第一行两个整数N, M

接下来N行,每行M个整数。

【输出格式】

两个数,用空格隔开,第一个数为满足条件的矩阵的面积,第二个数为该矩阵各元素之和。

【样例输入】

3 7

1 1 1 0 2 1 1

1 1 1 0 1 1 1

1 1 1 0 1 1 1

【样例输出】

9 9

【数据范围】

对于30%的数据,R,C<=10;

对于60%的数据,R,C<=100;

对于100%的数据,R,C<=1000。

0 <= 输入的其他整数 <= 10^9

题解

一开始预处理前缀和,然后二分正方形边长,枚举正方形的位置即可。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

int n,m,a[1005][1005],ans1;
long long sum[1005][1005],sum0[1005][1005],ans2=1LL<<60;
bool checkzero(int x,int y,int len)
{
    int newx,newy;
    newx=x+len-1,newy=y+len-1;
    return sum0[newx][newy]-sum0[x-1][newy]-sum0[newx][y-1]+sum0[x-1][y-1]==0;
}

bool check(int len)
{
    int i,j;
    for(i=1;i+len-1<=n;i++)
      for(j=1;j+len-1<=m;j++)
        if(checkzero(i,j,len)) return true;
    return false;
}
int main()
{
    int i,j,nowsum0,l,r,mid,nowi,nowj;
    long long nowsum;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
      for(j=1;j<=m;j++)
        scanf("%d",&a[i][j]);
    for(i=1;i<=n;i++)
    {
        nowsum=0LL;
        nowsum0=0;
        for(j=1;j<=m;j++)
        {
            nowsum+=a[i][j];
            nowsum0+=a[i][j]==0;
            sum[i][j]=sum[i-1][j]+nowsum;
            sum0[i][j]=sum0[i-1][j]+nowsum0;
        }
    }
    l=1;
    r=n<m?n:m;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(check(mid))
        {
           ans1=mid;
           l=mid+1;
        }
        else r=mid-1;
    }
    printf("%d ",ans1*ans1);

    for(i=1;i+ans1-1<=n;i++)
      for(j=1;j+ans1-1<=m;j++)
        if(checkzero(i,j,ans1))
        {
            nowi=i+ans1-1;
            nowj=j+ans1-1;
            ans2=min(ans2,sum[nowi][nowj]-sum[i-1][nowj]-sum[nowi][j-1]+sum[i-1][j-1]);
        }
    printf("%lld",ans2);
    return 0;
}
时间: 2024-11-04 14:06:30

【2016福建省夏令营Day1】数据结构的相关文章

【2016常州一中夏令营Day1】

Problem 1. suffix给定一个单词,如果该单词以 er. ly 或者 ing 后缀结尾,则删除该后缀(题目保证删除后缀后的单词长度不为 0),否则不进行任何操作.Input输入一行,包含一个单词(单词中间没有空格,每个单词最大长度为 32)Output输出按照题目要求处理后的单词.Examplesuffix.in          suffix.outreferer          referScoring? 对于 40% 的数据,单词最大长度不超过 5. 题解 无可奉告 #inc

2017福建夏令营Day1(数据结构)

工作团队 [问题描述] 一家公司有??名员工,刚开始每个人单独构成一个工作团队. 有时一项工作仅凭一个人或一个团队难以完成,所以公司会让某两个 人所在的团队合并. 但有的工作属于闷声大发财类型的,不适合多人做,所以公司有时也 会让一个人从他当前所在的团队中分离出来,构成单独的团队. 公司也要对当前团队的情况进行了解,所以他们也会询问一些问题, 比如某两个人是否属于同一工作团队,某个人所在的团队有多少个人,或 者当前一共有多少个工作团队. 作为该公司的软件服务商,你的任务便是实现一个实时的操作和查

【口胡】简谈福建省夏令营

Day1 t1:线段树区间修改 t2:字符串哈希+尺取 t3:dp Day2 t1:乱搞 t2:贪心 t3:八数码.各种搜索+剪枝 Day3 三题搜索 Day4 t1 t3普及组 t2:设状态f[i][j][k],前i行,j列一个,k列二个,每行每列最多两个炮.然后dp Day5 t1:正反计算一次最大子段和O(n) 枚举分界点 t2:用f(i,x,y,a,b)表示从1,1到x,y,从N,N到a,b,路径上相同的方案数,压掉y,b两维 t3:考虑次方的和可以这样计算 用表示后i个能获得的最大价值

2016计算机考研:数据结构常用算法精析

不知道博客园有没有计算机专业的考研党,希望列举的计算机考研考点能帮助大家吧,以下就是数据结构常用算法精析,如果大家看有什么不对的地方,欢迎纠错指正啊哈哈哈.2016考研加油!!!!!!!!! 内部排序(在内存中进行的排序不需要访问外存的)外部排序(排序量很大,通过分批的读写外存,最终完成排序) 稳定排序和非稳定排序:看相同记录的相对次序是否回发生改变.主要看在排序过程中的比较是不是相邻记录,如果是相邻比较,一定是稳定的排序.如果不是相邻的比较,就是不稳定的. 内排序方法 截止目前,各种内排序方法

清北学堂学习总结 day1 数据结构 练习

1.二叉搜索树 STL set直接做就可以了 2.树状数组+差分数列: codevs 1081 线段树练习 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有数都增加X 2:询问第i个数是什么? 输入描述 Input Description 第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数.如果第一个数是1,后接3个正

2015北大夏令营day1 B:An Idea of Mr. A

题意:给定一个范围l,r计算i,j(i<j)属于这个范围内的gcd(2^(2^i)+1,2^(2^j)+1)的总和. 思路:费马数的应用,让我惊呆的是当年居然有123个人会做,我tm毛都不会.. 其实就是任意两个费马数都互质,就这样.. 1 #include<algorithm> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<iostream> 6 #

[蒟蒻修炼计划][谜之吐槽]FJ省夏令营day1

T1 Description 给出n个矩形的顶点坐标(每个矩形的底边都在x轴上),求这n个矩形所组成图形的轮廓线的顶点. Input 第一行一个整数n,表示矩形个数. 以下n行,每行3个整数,分别表示矩形的x坐标区间及矩形的高度h[i]. Output 第一行一个整数m,表示轮廓线顶点个数. 以下m行,每行一个坐标表示轮廓线上的顶点.从左到右遍历轮廓线并顺序输出顶点.第一个和最后一个节点的y坐标必然为0. Sample Input 2 3 0 2 4 1 3 Sample Output 6 0

YAML书写规则与数据结构

YAML 是一种简洁的非标记语言.YAML以数据为中心,使用空白,缩进,分行组织数据,从而使得表示更加简洁易读. 基本规则 YAML有以下基本规则: 1.大小写敏感 2.使用缩进表示层级关系 3.禁止使用tab缩进,只能使用空格键 4.缩进长度没有限制,只要元素对齐就表示这些元素属于一个层级. 5.使用#表示注释 6.字符串可以不用引号标注 三种数据结构 1.map,散列表 使用冒号(:)表示键值对,同一缩进的所有键值对属于一个map,示例: # YAML表示 age : 12 name : h

聊一聊前端模板与渲染那些事儿

欢迎大家收看聊一聊系列,这一套系列文章,可以帮助前端工程师们了解前端的方方面面(不仅仅是代码): https://segmentfault.com/blog/frontenddriver 作为现代应用,ajax的大量使用,使得前端工程师们日常的开发少不了拼装模板,渲染模板.我们今天就来聊聊,拼装与渲染模板的那些事儿. 如果喜欢本文请点击右侧的推荐哦,你的推荐会变为我继续更文的动力 1 页面级的渲染 在刚有web的时候,前端与后端的交互,非常直白,浏览器端发出URL,后端返回一张拼好了的HTML串