zoukankan      html  css  js  c++  java
  • [Offer收割]编程练习赛9,10

    题目1 : 闰秒

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    计算机系统中使用的UTC时间基于原子钟,这种计时方式同“地球自转一周是24小时”的计时方式有微小的偏差。为了弥补这种偏差,我们偶尔需要增加一个“闰秒”。  

    最近的一次闰秒增加发生在UTC时间2016年的最后一天。我们在2016年12月31日23时59分59秒和2017年1月1日0时0分0秒之间增加了这样一秒:2016年12月31日23时59分60秒,记作2016-12-31 23:59:60。  

    目前一共增加了27次闰秒,具体添加的时间见下表:

    给出两个时间,请你判断在考虑闰秒的情况下,这两个时间间隔多少秒。  

    输入

    两个时间各占一行,格式是yyyy-MM-dd HH:mm:ss,范围在1970-01-01 00:00:00至2017-03-12 23:59:59之间。保证第一个时间不晚于第二个时间。

    输出

    两个时间间隔多少秒。

    样例输入
    2016-12-31 23:59:59 
    2017-01-01 00:00:00
    样例输出
    2

    暴力模拟就好了,用ans[2]-ans[1]。

    #include <stdio.h>
    #include <cstring>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    ll ans[5];
    int Y[15]= {0,31,28,31,30,31,30,31,31,30,31,30,31}; //nor
    char c[3][3][33]; // 0 y-m-d  1 h-mi-s
    int y[5],m[5],d[5],h[5],mi[5],s[5];
    int data[3000][5];
    bool runnian(int a)
    {
        if((a%4==0&&a%100!=0)||a%400==0) return 1;
        else return 0;
    }
    void debug()
    {
        printf("%d %d %d**
    ",y[1],m[1],d[1]);
        printf("%d %d %d
    ",h[1],mi[1],s[1]);
        printf("%d %d %d
    ",y[2],m[2],d[2]);
        printf("%d %d %d
    ",h[2],mi[2],s[2]);
    }
    void init()
    {
        memset(ans,0,sizeof(ans));
        memset(y,0,sizeof(y));
        memset(m,0,sizeof(m));
        memset(d,0,sizeof(d));
        memset(h,0,sizeof(h));
        memset(mi,0,sizeof(mi));
        memset(s,0,sizeof(s));
        data[1972][1]=1;
        data[1972][2]=1;
        for(int i=1973; i<=1979; i++) data[i][2]=1;
        for(int i=1981; i<=1983; i++) data[i][1]=1;
        data[1985][1]=1;
        data[1987][2]=1;
        data[1989][2]=1;
        data[1990][2]=1;
        for(int i=1992; i<=1994; i++) data[i][1]=1;
        data[1995][2]=1;
        data[1997][1]=1;
        data[1998][2]=1;
        data[2005][2]=1;
        data[2008][2]=1;
        data[2012][1]=1;
        data[2015][1]=1;
        data[2016][2]=1;
    }
    
    ll ansy=365*24*3600;
    ll calnian(int y)
    {
        ll ans=0;
        for(int i=1970; i<=y; i++) //
        {
            ans+=ansy;
            if(runnian(i)) ans+=24*60*60;
            if(data[i][1]) ans++;
            if(data[i][2]) ans++;
        }
        return ans;
    }
    
    ll calyue(int y,int m)
    {
        ll ans=0;
        for(int j=1; j<=m; j++) //
        {
            ans+=Y[j]*24*60*60;
            if(j==2&&runnian(y)) ans+=24*60*60; //闰年2月+一天
            if(j==6&&data[y][1]) ans++;//闰秒也要
            if(j==12&&data[y][2]) ans++;
        }
        return ans;
    }
    
    ll calday(int y,int m,int d)
    {
        int f=0;
        ll ans=0;
        if(runnian(y)&&m==2) ans+=24*3600;
        ans+=d*24*3600;
        if(m==6&&data[y][1]) ans++;
        return ans;
    }
    
    int main()
    {
        init();
        for(int i=1; i<=2; i++)
            scanf("%d-%d-%d %d:%d:%d",&y[i],&m[i],&d[i],&h[i],&mi[i],&s[i]);
            //debug();
        for(int x=1; x<=2; x++)
        {
            ans[x]+=calnian(y[x]-1);
            ans[x]+=calyue(y[x],m[x]-1);
            ans[x]+=calday(y[x],m[x],d[x]-1);
            ans[x]+=h[x]*3600;
            ans[x]+=mi[x]*60;
            ans[x]+=s[x];
        }
        printf("%lld
    ",ans[2]-ans[1]);
        return 0;
    }

    题目2 : 水陆距离

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    给定一个N x M的01矩阵,其中1表示陆地,0表示水域。对于每一个位置,求出它距离最近的水域的距离是多少。  

    矩阵中每个位置与它上下左右相邻的格子距离为1。

    输入

    第一行包含两个整数,N和M。

    以下N行每行M个0或者1,代表地图。

    数据保证至少有1块水域。

    对于30%的数据,1 <= N, M <= 100  

    对于100%的数据,1 <= N, M <= 800

    输出

    输出N行,每行M个空格分隔的整数。每个整数表示该位置距离最近的水域的距离。

    样例输入
    4 4  
    0110  
    1111  
    1111  
    0110
    样例输出
    0 1 1 0  
    1 2 2 1  
    1 2 2 1  
    0 1 1 0

    宽搜,只搜终点,搜过的点再加到队列里。

    #include <queue>
    #include <vector>
    #include <stdio.h>
    #include <iostream>
    #include <string.h>
    #include <stdlib.h>
    #include <algorithm>
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int maxn=810;
    int n,m;
    int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
    int vis[maxn][maxn];
    char str[maxn][maxn];
    int ans[maxn][maxn];
    struct point{
        int x,y;
    }sna[maxn*maxn];
    struct edge{
        int x,y,step;
    };
    queue<edge>que;
    void bfs(){
        edge c,ne;
        while(!que.empty()){
            c=que.front();que.pop();
            for(int i=0;i<4;i++){
                int xx=c.x+dir[i][0];
                int yy=c.y+dir[i][1];
                if(xx<0||xx>n-1||yy<0||yy>m-1||vis[xx][yy]==1) continue;
    //            ans[xx][yy]=c.step+1;
                ans[xx][yy]=c.step+1;
                ne.x=xx;ne.y=yy;ne.step=c.step+1;
                vis[ne.x][ne.y]=1;
                que.push(ne);
            }
        }
    }
    int main(){
        while(scanf("%d%d",&n,&m)!=-1){
            while(!que.empty()) que.pop();
            memset(vis,0,sizeof(vis));
            for(int i=0;i<n;i++) scanf("%s",str[i]);
            for(int i=0;i<n;i++) for(int j=0;j<m;j++) ans[i][j]=inf;
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    if(str[i][j]=='0'){
                        ans[i][j]=0;vis[i][j]=1;
                        edge c;
                        c.x=i;c.y=j;c.step=0;
                        que.push(c);
                    }
                }
            }
            bfs();
    //        for(int i=0;i<n;i++) for(int j=0;j<m;j++) ans[i][j]=min(ans[i][j],st[i][j]);
            for(int i=0;i<n;i++){
                for(int j=0;j<m;j++){
                    if(j==m-1) printf("%d
    ",ans[i][j]);
                    else printf("%d ",ans[i][j]);
                }
            }
        }
        return 0;
    }

    题目2 : 出勤记录II

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    小Hi的算法课老师每次上课都会统计小Hi的出勤记录。迟到会被记录一个L,缺席会被记录一个A,按时上课会被记录一个O。

    一学期结束,小Hi的出勤记录可以看成是一个只包含LAO的字符串,例如"OOOOLOOOLALLO……"。

    如果小Hi整学期缺席不超过1次,并且没有连续3次迟到,小Hi的出勤记录就算合格。  

    现在给出字符串的长度N,小Hi想知道长度为N的出勤记录中,合格的记录总共有多少种。  

    例如长度为3的合格出勤记录有19种:OOO OOL OOA OLO OAO LOO AOO OLL OLA OAL LOL LOA AOL LLO LAO ALO LLA LAL ALL。

    输入

    一个整数N(1 <= N <= 100000)。

    输出

    长度为N的合格记录总数。由于结果可能很大,你只需输出结果模109+7的余数。

    样例输入
    3
    样例输出
    19

    DP,一共6种状态。

    012代表有A,0代表以A或O结尾,1代表以L结尾,2代表以LL结尾。

    345代表无A,3代表以O结尾,4代表以L结尾,5代表以LL结尾。

    而6代表总数。

    转移一下就好了,转移方程见代码。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const ll mod=1e9+7;
    ll dp[100005][10];
    int main()
    {
        int n;
        memset(dp,0,sizeof(dp));
        dp[1][6]=3;
        dp[2][0]=3;dp[2][1]=dp[2][4]=dp[2][5]=1;
        dp[2][3]=2;dp[2][2]=0;dp[2][6]=8;
        for(int i=3;i<=100000;i++)
        {
            dp[i][0]=(dp[i-1][0]+dp[i-1][1]+dp[i-1][2]+
            dp[i-1][3]+dp[i-1][4]+dp[i-1][5])%mod;
            dp[i][1]=dp[i-1][0]%mod;
            dp[i][2]=dp[i-1][1]%mod;
            dp[i][3]=(dp[i-1][3]+dp[i-1][4]+dp[i-1][5])%mod;
            dp[i][4]=dp[i-1][3]%mod;
            dp[i][5]=dp[i-1][4]%mod;
            dp[i][6]=(dp[i][0]+dp[i][1]+dp[i][2]+
            dp[i][3]+dp[i][4]+dp[i][5])%mod;
        }
        while(scanf("%d",&n)!=EOF)
        printf("%lld
    ",dp[n][6]);
        return 0;
    }
  • 相关阅读:
    android studio首次运行出错
    分享4种CSS3效果(360度旋转、旋转放大、放大、移动)
    重温CSS:Border属性
    CSS3之过渡Transition
    ASP.NET(C#)--Repeater中生成“序号”列
    Android开发过程问题集锦(Continuous updating)
    ZOJ Problem Set Vol 1(Update paste)
    MapReduce基本原理及应用
    Tensorflow之基于MNIST手写识别的入门介绍[转载]
    Tensorflow 计算模型——计算图
  • 原文地址:https://www.cnblogs.com/Ritchie/p/6612871.html
Copyright © 2011-2022 走看看