• 8.25 欢乐emmm赛


    三道题

    A现代艺术
    时间限制 : - MS   空间限制 : 165536 KB 
    评测说明 : 1s
    问题描述

    何老板是一个现代派的艺术家。他在一块由n*n的方格构成的画布上作画。一开始,所有格子里的数字都是0。
    何老板作画的方式很独特,他先后给N^2个子矩阵涂上了颜色,每次都是从1到N^2这些数字中选一个给对应矩阵全部填上该数字。比如:
    第1步,他选数字2填在了一个子矩阵上。如下图:

    2 2 2 0 
    2 2 2 0 
    2 2 2 0 
    0 0 0 0
    第2步,他用数字7填在了一个子矩阵上:
    2 2 2 0 
    2 7 7 7 
    2 7 7 7 
    0 0 0 0
    第3步,他用数字3填在了一个子矩阵上:
    2 2 3 0 
    2 7 3 7 
    2 7 7 7 
    0 0 0 0
    以此填涂下去,直到1到N^2中每个数字都被用过了一次(每个数字只能被使用一次)。
    现在何老板已经完成了他的艺术创作,你得到了最后的图形。
    何老板问你,根据这幅作品,你能够推断出第一步填涂的数字可能是哪些呢?输出第一步填涂可能的数字的个数。
    
    输入格式

    第一行,一个整数N(1<=N<=1000)
    接下来一个N*N的数字矩阵,表示画作最终的样子。

    输出格式

    一个整数,表示第一步填涂可能的数字个数。

    样例输入

    4
    2 2 3 0 
    2 7 3 7 
    2 7 7 7 
    0 0 0 0

    样例输出

    14

    提示

    样例解释,数字2是最先被填涂的。数字3显然在数字7后才填涂,数字7显然在数字2后被填涂。
    因为看不到其他数字,所以,这些数字有可能出现在数字2之前,后来被覆盖了。

    第一题  以为是个一眼题  但是忽略了很多情况

    开始以为只需要讨论数字的个数(太单纯  :)

    来说正解  二维查分讨论重叠部分:

    通过对角线的数值+二维查分添加(不用查分就是暴力  会超时)

    #include<stdio.h> 
    #include<bits/stdc++.h>
    #include<cctype>
    using namespace std;
    int n,f[1005][1005],a,g,ff,mark[1000005],summ[1005][1005],markx[1000005],marky[1000005],markxx[1000005],markyy[1000005],sum[1005][1005],k[1000005],ans;
    char buf[1<<20],*p1,*p2;  
    #define GC (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?0:*p1++)  
    template<class T> inline void read(T &n){  
        char ch=GC;T w=1,x=0;  
        while(!isdigit(ch)){if(ch=='-') w=-1;ch=GC;}  
        while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=GC;}  
        n=x*w;  
    }
    int main()
    {
    mark[0]=1;
    read(n);
    for(int i=1;i<=n*n;i++)markx[i]=marky[i]=1e9;
    for(int i=1;i<=n;i++)
       for(int j=1;j<=n;j++)
    {
    read(a);
    f[i][j]=a;
    if(mark[f[i][j]]==0)
    {
    mark[f[i][j]]=1;
    g++;
    }
    markx[f[i][j]]=min(i,markx[f[i][j]]);
    marky[f[i][j]]=min(j,marky[f[i][j]]);
    markxx[f[i][j]]=max(i,markxx[f[i][j]]);
    markyy[f[i][j]]=max(j,markyy[f[i][j]]);//更新一下对角线 
    }
    if(g==1)cout<<n*n-1;
    else{ 
       for(int i=1;i<=n*n;i++)
       {
        if(mark[i]==1)
        {
        sum[markx[i]][marky[i]]+=1;
        sum[markxx[i]+1][marky[i]]-=1;
        sum[markx[i]][markyy[i]+1]-=1;
        sum[markxx[i]+1][markyy[i]+1]+=1;
        }
       }
    
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    {
    summ[i][j]=sum[i][j]+summ[i-1][j]+summ[i][j-1]-summ[i-1][j-1];
    if(summ[i][j]>1)
    {
    if(k[f[i][j]]==0)
    {
    k[f[i][j]]=1;
    ff++;          
    }
    }
    }
    ans=n*n-ff;
    cout<<ans;
    }
    }
    B[JLOI2012]树
    时间限制 : - MS   空间限制 : - KB 
    评测说明 : 1s,128m
    问题描述

    在这个问题中,给定一个值S和一棵树。
    在树的每个节点有一个正整数,问有多少条路径的节点总和达到S。路径中节点的深度必须是升序的。
    假设节点1是根节点,根的深度是0,它的儿子节点的深度为1。路径不必一定从根节点开始。

    输入格式

    第一行是两个整数N和S,其中N是树的节点数。
    第二行是N个正整数,第i个整数表示节点i的正整数。
    接下来的N-1行每行是2个整数x和y,表示y是x的儿子。

    输出格式

    输出路径节点总和为S的路径数量。

    样例输入

    3 3
    1 2 3
    1 2
    1 3

    样例输出

    2

    提示

    对于100%数据,N<=100000,所有权值以及S都不超过1000。

    emmm考试的时候脑壳没怎么开机  而且关于树的问题学的不是很好 ,所以先看了c题,做过来的时候只有半个小时了,就想到了暴力。经nonstop的提醒+了一个dfs序优化。

    还出了一个小插曲,考试的时候数据范围100%的时候写成了10三次方,也就觉得暴力可以过,后来老板才说是写错了。最开始没开打范围60t了   增大数组之后就变成了90t

    下面是ac代码  还要剪枝优化

    #include<bits/stdc++.h> 
    using namespace std;
    struct node{
        int en,ne;
    }e[200005];
    long long w[100005][25],f[100005][25],la[200005],a[100005],x,y,n,l,cnt,ans;
    void add(int x,int y)
    {
       e[++cnt].en=y;e[cnt].ne=la[x];la[x]=cnt;
    }
    
    void dfs(int x,int fa)
    {
        f[x][0]=fa;
        w[x][0]=a[x];
        for(int i=1;i<=20;i++)f[x][i]=f[f[x][i-1]][i-1],w[x][i]=w[x][i-1]+w[f[x][i-1]][i-1];
        int p=x,len=l;
        for(int i=20;i>=0;i--)
        if(f[p][i]&&w[p][i]<len)len=len-w[p][i],p=f[p][i];
        if(w[p][0]==len)ans++;
        for(int i=la[x];~i;i=e[i].ne)if(e[i].en!=fa)dfs(e[i].en,x);
    }
    
    int main()
    {
        cin>>n>>l;
        memset(la,-1,sizeof(la));
        for(int i=1;i<=n;i++)cin>>a[i];
        for(int i=1;i<n;i++)
        {   
            cin>>x>>y;
            add(x,y);
            add(y,x);
        }
       dfs(1,0);
        cout<<ans;
    }
    C旅店
    时间限制 : - MS   空间限制 : - KB 
    评测说明 : 1s,256m
    问题描述

    一条笔直的公路旁有N家旅店,从左往右编号1到N,其中第i家旅店的位置坐标为
    旅人何老板总在赶路。他白天最多行走个单位的距离,并且夜间必须到旅店休息。
    何老板给你Q个询问,每个询问的都由两个整数构成,其中第i个询问的格式为,,表示他想知道自己从号旅店走到号旅店,最少需要花费多少天?

    输入格式

    第一行,一个整数N

    第二行,N个空格间隔的整数  表示每个旅店的坐标

    第三行,一个整数L

    第四行,一个整数Q

    接下来Q行,每行两个整数,表示一次询问

    输出格式

    Q行,每行一个整数,依次表示对应询问的答案

    样例输入

    9
    1 3 6 13 15 18 19 29 31
    10
    4
    1 8
    7 3
    6 7
    8 5

    样例输出

    4
    2
    1
    2

     

    这道题嘛也是直接暴力捞了40分  其实可以lb一下就60了

    这道题的正解是用倍增/分块  做:)

    还有nkoj上这道题如果用cin的话要超时45t

    改成scanf就愉快ac啦

    #include<stdio.h> 
    #include<bits/stdc++.h> 
    #include<cctype>
    using namespace std;
    long long n,l,ll,q,r,f[100005][35],a[100005],ans,d;
    int main()
    {
    scanf("%lld",&n);
    for(int i=0;i<n;i++)scanf("%lld",&d),a[i]=d;
    scanf("%lld%lld",&l,&q);
    for(int i=0;i<n;i++)f[i+1][0]=upper_bound(a,a+n,a[i]+l)-a;    
    for(int j=1;j<=30;j++)
       for(int i=1;i<=n;i++)f[i][j]=f[f[i][j-1]][j-1];
     long long ans;
       for(int i=1;i<=q;i++)
       {
           scanf("%lld%lld",&l,&r);
           if(l>r)swap(l,r);
           ans=0;
           for(int i=30;i>=0;i--){
               if(f[l][i]<r){
                   ans+=(long long)(1<<i);
                   l=f[l][i];
               }
           }
           printf("%lld
    ",ans+1);
        } 
    }
       
       
       

     最后附上一段手写的优秀的但是输入有点问题的快读 来自马悦波童鞋

    #include<cctype>
    char buf[1<<20],*p1,*p2;  
    #define GC (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?0:*p1++)  
    template<class T> inline void read(T &n){  
        char ch=GC;T w=1,x=0;  
        while(!isdigit(ch)){if(ch=='-') w=-1;ch=GC;}  
        while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=GC;}  
        n=x*w;  
    }

     

  • 相关阅读:
    控制一个cell不可被移动到另外一个section中
    core data 手动修改 .xcodatamodeld 文件 和 po 生成的 模型类 注意事项
    stringByTrimmingCharactersInSet 取出string 前后空格
    项目架构简述
    nil NULL [NSNULL null]
    如何定义一个应用之间调用的ios 本地URL
    UITableView隐藏多余的分割线
    解决UItableView cell的间隔线 separatorStyle ( plain group 两种类型)
    模拟器 真机 测试 内存消耗 资源对比
    微服务架构:Eureka集群搭建
  • 原文地址:https://www.cnblogs.com/cocacolalala/p/11408395.html
Copyright © 2020-2023  润新知