2019.6.28 校内测试 T1 Jelly的难题1

这题面有点难理解,建议直接跳到题意解释那一部分(虽然我觉得解释的不大对,但按照解释来做确实能AC);

按照“题意解释”的思路来思考这个题,那么就十分的简单了:

1.首先要读入这个字符矩阵,可以用cin(会不会TLE不知道),这里我用的是getchar读入;

2.从‘ * ’开始一遍广搜,记录一下每个‘ # ’被搜索到的时间,直到所有的点都被遍历过;

3.找出所有‘ # ’的位置时间最大的那个,就是第一问的答案,暂且记为much;

4.因为走过的格子每单位时间会增加1点高度,所以对于某一个格子 i,若遍历它的最短时间是ti,那么它对答案作出的贡献就是:much - ti + 1,将每个格子的贡献累加起来就是第二问的答案啦;

5.考虑判断无解的情况:O(nm)暴力扫一遍所有的格子,如果出现了遍历时间为0的情况(也就是说某个格子没有被遍历到),说明无解;

代码如下:

#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
using namespace std;
const int mod=19260817;
char read()                              //自定义字符读入
{
    char ch=getchar();
    while(ch!=‘*‘&&ch!=‘o‘&&ch!=‘#‘) ch=getchar();  //不是题目中的三种字符就一直往下读
    return ch;
}
struct juanzi                            //开一个结构体,存每一个格子的信息:最先被遍历的时间是t,坐标是(x1,y1)
{
    int t,x1,y1;
}b[250001];
queue<juanzi> q;                         //开一个结构体类型的队列
char a[501][501];                        //存输入的字符矩阵
int n,m,start,endd,xx,yy;                //n*m的矩阵,打印机‘*‘的坐标是(start,endd),注意不要用end,好像会和STL里面的东西重名(我CE我知道)
int dx[5]={0,1,0,-1,0};                  //四个方向
int dy[5]={0,0,-1,0,1};
int vis[501][501];                       //存每个点被遍历的时间
int ans,much;
void bfs()
{
    q.push((juanzi){0,start,endd});      //起点入队
    juanzi f;
    while(!q.empty())                    //其实我们每一步都判断是否将所有点都遍历过,只需判队列非空就好啦,队列为空就说明无法再遍历到其他的点了
    {
        f=q.front();
        q.pop();
        for(int i=1;i<=4;i++)
        {
            xx=f.x1+dx[i];               //往四个方向走
            yy=f.y1+dy[i];
            if(a[xx][yy]==‘#‘&&vis[xx][yy]==0)   //如果可以走并且之前没走过,那就走
            {
                vis[xx][yy]=f.t+1;       //到这个格子的时间是上一个格子的时间再加一
                q.push((juanzi){f.t+1,xx,yy});   //入队去遍历下面的格子
            }
        }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
       for(int j=1;j<=m;j++)
          {
                a[i][j]=read();
                if(a[i][j]==‘*‘)           //记录下打印机‘*‘的位置
                {
                        start=i;
                    endd=j;
                    vis[i][j]=-1;        //把不能遍历的点的时间全赋成-1
              }
              if(a[i][j]==‘o‘) vis[i][j]=-1;    //花盆的位置
          }
    bfs();                               //核心代码:广度优先搜索
    for(int i=1;i<=n;i++)                //判无解的情况
       for(int j=1;j<=m;j++)
          if(vis[i][j]==0)
          {
              cout<<-1;return 0;
          }
    for(int i=1;i<=n;i++)
       for(int j=1;j<=m;j++)
          much=max(much,vis[i][j]);      //找最后被遍历到的点所需要的时间
    printf("%d\n",much);
    for(int i=1;i<=n;i++)
       for(int j=1;j<=m;j++)
       {
              if(vis[i][j]>0)               //排除了打印机‘*‘和花盆‘o‘的位置
              {
                      ans=(ans+(much-vis[i][j]+1)%mod)%mod;  //每个格子的贡献
           }
       }
    printf("%d",ans);
    return 0;
}
/*
其实由于数据有锅,无解的情况没有看出来,当成有解的情况做了;
AC代码要注释掉那个判断无解的情况QwQ~
但加上那一段判无解的代码应该才是最正确的
*/

原文地址:https://www.cnblogs.com/xcg123/p/11105602.html

时间: 2024-08-29 09:18:13

2019.6.28 校内测试 T1 Jelly的难题1的相关文章

2019.7.24 校内测试 分析+题解

T1 地雷 题目很简单呢,就是求哪个数只出现了一次就可以了哦~ 我一开始的想法是桶排(这也是最单纯最简单的想法吧~),但是空间开 232 肯定会炸的,而且时间好像也会炸掉. 然后左边的 ych 大佬小声说了一句:“得换个算法.” 嗯,确实要换个算法,然后我就觉得新算法一定是不用开数组,直接输完数据就能出答案的那种! 然后不知道怎么就想到了 zhx 讲博弈论的时候输入的同时将 ……(一些稀奇古怪的东西) 异或起来就是答案,这不正好跟我理想的新算法很像嘛? 异或异或?咦,又想到了六月底那次考试有个叫

18清明校内测试T1

消失的数字(number) Time Limit:1000ms   Memory Limit:128MB 题目描述 rsy拥有n个数,这n个数分别是a1,a2,…,an. 后来出现了一个熊孩子zhw,用橡皮擦去了其中若干个数字,并且打乱了剩下的数字.rsy赶到现场后只剩下了m个数字b1,b2,…,bm,她想知道哪些数字被擦去了. 现在你需要告诉rsy被擦去的n-m个数是什么. 输入格式(number.in) 第一行一个数n,第二行n个数ai,表示一开始的数字. 第三行一个数m,第四行m个数bi,

2019.9.28 csp-s模拟测试54 反思总结

咕咕咕的冲动如此强烈x T1x: 看完题目想了想,感觉把gcd不为1的强行放在一组,看作一个连通块,最后考虑连通块之间的组合方式就可以了. 然后维护这个连通块可以写并查集可以连边跑dfs怎么着都行… 然而我在处理数字分解质因数这里T掉了,原因是一个很显然的优化写法我基本没怎么写过.线性筛的时候记录每个数是被哪个质数标记过的,分解一个数的时候直接处理记录下来的质数就可以. #include<iostream> #include<cstdio> #include<cmath>

2019/10/2 图论测试小结

T1: 题意:求一棵树上两条点不交路径,使它们的点权之和最大: 思考过程:联想到了一个相似的问题——树上求k条边不交路径的最大边权和,想到了拆点为边,很快发现不对.考虑到仅有两条边于是先求出一条直径,再分类讨论看第二条路是否经过第一条直径,不经过则bfs求最大值,经过则对直径上每一个点求一个最长的.以它为端点的.不经过直径上点的链,然后贪心求最大值. 题解:同思路: T2: 题意:一个完全图,一课树,完全图上两点之间的距离等于树上两点之间的距离,在完全图上求最长哈密顿路径: 思考过程:没想拿满分

2019.10.28~2019.10.31考试总结

连续几天的考试都没有总结,今天有些时间,总结一下这几场考试的情况. 10.28场 开场先读题,然后推了推T2,发现是水题.出于对期望的恐惧,没有选择研究T3,而是回头肝T1,想了很久,没有思路.打完T2,自己搓了一些数据,过了,回头打了T1的暴搜,再打了一个表,似乎部分分挺多的.再做T3,有点思路,但思路并不清晰,于是打了特殊数据就完了. 期望得分:70+100+20=190 最终得分:30+100+20=150 结果T1是DP,没看出来.唔...原题,地精部落,题果然还是做的太少了,有些人做过

2019年终总结----一个测试的成长年

从今年5月开始写下第一篇博客,到现在还是有几十篇了,写的大致是我不懂到懂的东西.我很高兴我能够坚持写,也希望能继续写下去. 2019年对我来说关键字应该是--收获 今天的我确实成长了不少,令我感到开心的是我不光测试能力得到了成长而是今年我算是一只脚进入了开发的大门. 今年2月我跳槽到了现在的公司,一个小型公司,入职之后就我一个测试属于研发组.入职之后负责三个项目的测试工作,由于都是上线了的产品,所以还是算比较稳定的没有多少BUG.这个工作完成之后我写了其中两个项目的自动化测试,主要还是用于做监控

6.28数论测试

(hao.cpp/c/pas) [问题描述]从1− N中找一些数乘起来使得答案是一个完全平方数,求这个完全平方数最大可能是多少.[输入格式]第一行一个数字N.[输出格式]一行一个整数代表答案对100000007取模之后的答案.[样例输入]7[样例输出]144[样例解释]但是塔外面有东西.[数据规模与约定]对于20%的数据,\begin{equation*}1\leq N\leq 100 \end{equation*}.对于50%的数据,\begin{equation*}1\leq N\leq 5

2017-9-3 校内模拟T1卡片card

题意:有三种字母,可以用两个不同的换一个第三种字母,两个相同的换一个同种字母(即消去一个),问最后剩下的字母. 第一题显然是if题,总体来说只有三种情况: 1.有三种不同的>>输出"BGR" 2.有两种不同的:{ (1)两种都有超过一个>>情况1: (2)一种只有一个>>输出这种和未出现的字母 (3)两种都只有一个>>输出未出现的字母 }   3.只有一种字母>>输出这个字母 代码(极丑): 1 #include<ios

【8.15校内测试】【队列】【manacher】

dp??不能确定转移状态.考虑用优先队列储存最优决策点,可是发现当前选择最优不能保证最后最优,在后面可以将之前用过的替换过来. 比如数据: 3 5 4 6 只储存a[i]来决策不能延展到后面的状态,因此每次选择过后把b[i]加入队列,下次选择最优时如果选择到了b[i],则表示用之前选择过的来替换到当前状态. 这里我开了两个优先队列. 1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #define l