2020-4-26

 

请小伙伴们对自己AC的题目进行标记,注意每人只能标记一次!不知道的不要标记,恶意标记者将回收账号!!!

问题 D: 迷宫

时间限制: 1 Sec  内存限制: 128 MB
[提交] [状态]

题目描述

迷宫的管理员们决定在新开始的季节里使用新的墙纸。出于这个目的他们需要一个程序来计算迷宫内墙壁的面积。这就是你即将要做的工作。
我们把这个迷宫用一个N*N(3<=N<=33)的矩阵表示。一些矩阵单元包含一个“.”(这代表一个空的方块),另一些矩阵单元包含一个“#”(这代表一个用巨石砌成的石墙占据的方块)。全部方块的大小都为3*3平方米。

墙壁由迷宫的四周(除了作为迷宫出入口的左上角和右下角以外)以及那些标记为“#”的矩阵单元构成,除此之外没有其他的墙。在输入的矩阵里左上角和右下角永远是一个“.”。你的任务是计算迷宫里可见部分的墙壁的面积。换句话说,就是对迷宫的游客来说墙壁表面可见的部分。注意在两块相邻的石块之间没有空隙,即使两块石块在转角处相接触,我们都认为它们是相邻的。看看图示的例子:迷宫中可见的墙壁都用加粗的线条来描画。所有墙壁的高度都是三米。

输入

输入的第一行包含一个数字N。接下来的N行每行都包含有N个字符。每行描述了迷宫矩阵的一行。每行都只有“.”、“#”这两个字符并都以一个换行符结束。输入里没有任何的空格

输出

你的程序必须输出一个整数,即所需要的壁纸的准确面积。

样例输入 Copy

5 
..... 
...## 
..#.. 
..### 
.....

样例输出 Copy

198

 

这个写的好,洪水算法------ 

#include<bits/stdc++.h>
typedef unsigned long long ULL;
using namespace std;
typedef long long ll;
typedef pair<int,int>pp;
const int N=200010;
vector<int>v;
#define X first
#define Y second
priority_queue<int>q;
const int INF=1e9+1;
int a[505][505],pos[505][505],maxn=0,n;
void dfs(int x,int y)
{
    if(a[x][y]==0) return ;
    if(x<=0||x>n||y<=0||y>n) return ;
    if(pos[x][y]==1) return;
    a[x][y]=0;
    dfs(x-1,y);dfs(x+1,y);
    dfs(x,y-1);dfs(x,y+1);
}
int main()
{
   scanf("%d",&n);
   memset(a,-1,sizeof(a));
   for(int i=1;i<=n;i++)
   {
       char str[35];
       scanf("%s",str);
       for(int j=0;j<n;j++)
         {
             if(str[j]=='#') pos[i][j+1]=1;
         }
   }
   dfs(1,1);
   dfs(n,n);
   int ans=0;
   for(int i=1;i<=n;i++)
   {
       for(int j=1;j<=n;j++)
       {
           if(a[i][j]==0)
           {
               if(a[i-1][j]==-1) ans++;
               if(a[i+1][j]==-1) ans++;
               if(a[i][j-1]==-1) ans++;
               if(a[i][j+1]==-1) ans++;
           }
       }
   }
   printf("%d",(ans-4)*9);
    return 0;
}
 
 
 
/**************************************************************
    Problem: 15305
    User: 2019UPC110
    Language: C++
    Result: 正确
    Time:2 ms
    Memory:4020 kb
****************************************************************/

 

 

问题 E: MAX 的读书计划

时间限制: 1 Sec  内存限制: 128 MB
[提交] [状态]

题目描述

MAX 很喜欢读书,为了安排自己的读书计划,他会预先把要读的内容做好标记,A B 表示一个页段,即第 A 到 B 面,当然 A<B,若有两个页段 A-B,B-C,则可以直接记为 A-C,这样,他就可以一次看完,现在告诉你 n 个页段,请你帮他求出最长的一条页段,并输出这条页段的长度和组成它的页段个数。举个例子: 
有 6 个页段: 
2-7     1-3    3-12    12-20    7-10    4-50 
那么连续的页段就有: 
1-3,3-12,12-20 长度为 20-1+1=20 由 3 个页段组成 
2-7,7-10        长度为 10-2+1=9  由 2 个页段组成 
4-50             长度为 50-4+1=47 由 1 个页段组成 
那么最长的一条就是第三个,所以结果为 47 1。 
需要注意的是:如果有两条不一样的连续的页段长度同时为最大,那么取组成页段数多的一条. 
例子: 1-5,5-10,1-10 
输出: 10 2   

输入

第一行为一个整数n,n<500;
第二行到第n+1行,每行两个整数A,B,记录一个页段的信息。0<=A<B<500

输出

输出一个整数,即最长的页段的长度和组成它的页段数。 

样例输入 Copy

7 
1 5 
10 12 
3 10 
2 7 
2 10 
12 16 
7 9 

样例输出 Copy

15 3

提示

1-5  长度为5由1个页段组成
3-10,10-12,12-16  长度为14由3个页段组成
2-7,7-9  长度为8由2个页段组成
2-10,10-12,12-16  长度为15由3个页段组成

所以输出最长的页段的长度即15由3个页段组成

【数据规模】
对于30%的数据n<20,0<=A<B<500
对于100%的数据n<500,0<=A<B<500

 

#include<bits/stdc++.h>
typedef unsigned long long ULL;
using namespace std;
typedef long long ll;
typedef pair<int,int>pp;
const int N=200010;
vector<int>v;
#define X first
#define Y second
priority_queue<int>q;
const int INF=1e9+1;
int n,ans=0,fa[505],sum[505];
int d[505][505],maxn=0;
int main()
{
  scanf("%d",&n);
  for(int i=1;i<=n;i++)
  {
      int a,b;
      scanf("%d%d",&a,&b);
       d[a][b]=b-a+1;
       maxn=max(maxn,b);
  }
 for(int i=0;i<=maxn;i++)
 {
     for(int j=0;j<i;j++)
     {
         if(d[j][i]!=0)
         {
             if(sum[j]!=0)
             {
                 if(sum[i]<sum[j]+d[j][i])
                 {
                     sum[i]=sum[j]+d[j][i]-1;
                    fa[i]=j;
                 }
             }
 
 
         else
         {
           sum[i]=max(sum[i],d[j][i]);
         }
         }
 
     }
 }
 int ans1=0,ans2=0;
 
     for(int i=0;i<=maxn;i++)
     {
         ans1=max(ans1,sum[i]);
     }
 
 for(int i=0;i<=maxn;i++)
 {
     if(sum[i]==ans1)
     {
         int cnt=1,a=i;
         while(fa[a]!=0)
         {
             cnt++;
             a=fa[a];
         }
         ans2=max(ans2,cnt);
     }
 }
 printf("%d %d",ans1,ans2);
    return 0;
}
 
 
 
/**************************************************************
    Problem: 15306
    User: 2019UPC110
    Language: C++
    Result: 正确
    Time:2 ms
    Memory:3028 kb
****************************************************************/

 

问题 F: 趾压板矩阵

时间限制: 1 Sec  内存限制: 128 MB
[提交] [状态]

题目描述

第二天早晨,跑男队员们来到了风景秀丽的扬州瘦西湖,刚下车他们全都尖叫起来,没错,就是他们最怕的“趾压板”:
一块超级大的趾压板被分成了n行n列,每个小格子上都有一个数字。游戏规则是:观察一段时间后,把所有的数字拿掉,分别抽取一个行号i和列号j,说出这个位置上原来的数字是多少,如果不能说出正确的值,就要接受处罚,光脚从左上角1沿着顺序从小到大走到这个数字所在位置。

“捡漏王”王祖蓝思考了一会,马上找到了其中的奥秘,你呢?

 

输入

输入共一行,包含三个整数n,i,j,每两个整数之间用空格隔开,分别表示矩阵大小、待求的数所在的行号和列号。

 

输出

输出共一行,包含一个整数,表示相应矩阵中第i行和第j列的数。

样例输入 Copy

7 4 3

样例输出 Copy

18

提示

对于50%的数据,1≤n≤100;
对于100%的数据,1≤n≤30,000,1≤i≤n,1≤j≤n。

#include<bits/stdc++.h>
typedef unsigned long long ULL;
using namespace std;
typedef long long ll;
typedef pair<int,int>pp;
const int N=200010;
vector<int>v;
#define X first
#define Y second
priority_queue<int>q;
const int INF=1e9+1;
int main()
{
    ll n,a,b;
    scanf("%lld%lld%lld",&n,&a,&b);
    ll kk=a+b-1,ans=0;
    if(kk<=n)
    {
        ll sum=(1+kk-1)*(kk-1)/2;
        if(kk%2==0)//下往上
        {
            ans=sum+(kk-a+1);
        }
        if(kk%2==1)
        {
            ans=sum+(kk-b+1);
        }
    }
    else
    {
        ll sum=(1+n)*n/2;

        for(int i=1;i<kk-n;i++)
            sum+=(n-i);
        if(kk%2==0)
        {
            ans=sum+(b-(kk-n));
        }
        if(kk%2==1)
        {
            ans=sum+(a-(kk-n));
        }
    }
    printf("%lld",ans);
    return 0;
}


问题 G: 背菜谱

时间限制: 1 Sec  内存限制: 128 MB
[提交] [状态]

题目描述

扬州是中国四大菜系之一的淮扬菜系的发源地。中午,跑男们来到扬州菜根香饭店,这是家很有名的老字号,有着正宗的淮扬菜。狮子头不松不紧、蟹粉味很浓,扬州炒饭配料丰富,米粒颗颗饱满,煮干丝入口即化、汤头也很鲜……
不过吃饭前,他们还必须完成一项比赛——背菜谱,每人都有一本饭店的菜谱,在规定的时间看谁记住的菜名多。Angelababy发现菜谱中有的菜名字多一些,有的字少一些,多的菜名难背一点,少的菜名好背一点,根据Angelababy的经验,她能一眼看出背一个菜名需要的时间,以分钟记。
开始背菜谱的时间是yyyy年mm月dd日hh时min分,开始测试的时间是yyyy'年mm'月dd'日hh'时min'分。那么测试之前她最多能背多少个菜名呢?

 

输入

第一行一个整数n,表示字典中的单词数,n≤5000。
接下来n行,每行一个整数表示背这个单词需要用的时间,以分钟记,小于等于10000。
接下来两行依次是开始背菜谱的时间和开始测试时间。

 

输出

输出共一行,包含一个整数,测试前最多能背出的菜名数。

样例输入 Copy

2
1
1
2007-06-23-11:59
2007-06-23-12:00

样例输出 Copy

1

提示

对于100%的数据,1≤n≤5000。

时间给出的格式是:yyyy-mm-dd-hh:min,例如:2007-06-23-02:00,采用24小时制,每天从00:00~23:59,年份从0000到9999。

[提交][状态]

#include<bits/stdc++.h>
typedef unsigned long long ULL;
using namespace std;
typedef long long ll;
typedef pair<int,int>pp;
const int N=200010;
vector<int>v;
#define X first
#define Y second
priority_queue<int>q;
const int INF=1e9+1;
ll n,a[50005];
int isrun(ll y)
{
    if (y % 400 == 0)
        return 1;
    if (y % 4 == 0 && y % 100 != 0)
        return 1;
    return 0;
}
int mon[]= { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
long long fun(ll y, ll mn, ll d, ll h, ll m)
{
    ll s = 0;
    mon[2] += isrun(y);
    for (int i = 1; i < mn; i++)
        s += mon[i]*1440;
    for (int i = 1; i < d; i++)
        s += 1440;
    for (int i = 0; i < h; i++)
        s += 60;
    s += m;
    mon[2] -= isrun(y);
    return s;
}
 
 
int main()
{
    scanf("%lld",&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%lld",&a[i]);
    }
    sort(a+1,a+1+n);
    ll y1,mo1,d1,h1,m1,y2,mo2,d2,h2,m2;
    long long int sum=0;
    scanf("%lld-%lld-%lld-%lld:%lld",&y1,&mo1,&d1,&h1,&m1);
    scanf("%lld-%lld-%lld-%lld:%lld",&y2,&mo2,&d2,&h2,&m2);
    for(int i=y1+1; i<=y2-1; i++)
    {
        sum+=1440*(365+isrun(i));
    }
    if (y1 != y2)
        sum += fun(y2, mo2, d2, h2, m2) + 525600 + isrun(y1) * 1440- fun(y1, mo1, d1, h1, m1);
    else
        sum += fun(y2, mo2, d2, h2, m2) - fun(y1, mo1, d1, h1, m1);
   // printf("%lld\n", sum);
    int ans=0;
    for(int i=1; i<=n; i++)
    {
        if(sum>=a[i])
            ans++;
        sum-=a[i];
        if(sum<=0) break;
    }
    printf("%d",ans);
    return 0;
}
 
/**************************************************************
    Problem: 15308
    User: 2019UPC110
    Language: C++
    Result: 正确
    Time:4 ms
    Memory:2420 kb
****************************************************************/

 

https://blog.csdn.net/qq_36392612/article/details/72633387

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值