[Codeup 25481] swan

莫名其妙还找到了另一个铟炔锶烃的OJ : Codeup墓地

25481: swan

时间限制: 1 Sec  内存限制: 128 MB
献花: 86  解决: 13
[献花][花圈][TK题库]

题目描述

两头白天鹅生活在一个部分湖面结了冰的湖泊中,湖面的形状为一个长方形,并且被分割成R行C列的小方格,某些方格中结了冰,这样的方格称之为冰格,其余的方格称之为水格。

冬天过去了,湖面上的冰渐渐开始溶解了,每一天与水相邻的冰格就将消融而转化为水格。所谓两个方格相邻是指它们在水平或垂直方向有公共边,两个呈对角的方格是不相邻的,下图给出样例数据的演化过程。

白天鹅只能在水中沿水平或垂直方向游动,写一个程序判断多少天后两只白天鹅才能够相会。

输入

输入文件第一行包含两个用空格隔开的整数R 和C,其中1≤R,C≤1500,接下来的R行每行包含C个字符,描述湖面的初始状态,‘·’表示水格,‘X’表示冰格,‘L’表示一只白天鹅。

输出

输出文件仅一行包含一个整数表示两只白天鹅等到相邻那一天所需的天数。

样例输入

8 17
...XXXXXX..XX.XXX
....XXXXXXXXX.XXX
...XXXXXXXXXXXX..
..XXXXX.LXXXXXX..
.XXXXXX..XXXXXX..
XXXXXXX...XXXX...
..XXXXX...XXX....
....XXXXX.XXXL...

样例输出

2

首先我们可以看到这个动态消融的过程非常铟炔锶烃, 但是仔细想想后我们发现, 每块冰都有一个固定的消融时刻, 而这个时刻可以通过BFS预处理出来.

预处理的方式是将所有水方块入队, 每次取队首结点更新其相邻结点, 更新后新结点入队. 处理直至队列为空.

从一个 $L$ 到另一个 $L$ 中的路径中的结点的融化时间的最大值即为此条路径可用的时间. 而我们的任务实际上就是找到最早可用的路径的可用时刻.

所以这个问题似乎就变成了最短路问题. 不过不同的是平常的最短路是最小化边权/点权的和, 而这次我们要最小化的是路径中边权/点权的最大值. 这种时候不用方, 祭出我们万能的OI三大玄学之一 $SPFA$ 来跑一遍就得出解了OwO

(原题似乎丧病地卡了 std::queue ...给出题人 $2147483647$ 个差评(╯‵□′)╯︵┻━┻然而懒得实现循环队列就开了 $30M$ 个结构体, 每个结构体里两个 int ...(炸内存边缘))

参考代码

GitHub

  1 #include <queue>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <iostream>
  6 #include <algorithm>
  7
  8 const int MAXN=1510;
  9
 10 struct Point{
 11     int x;
 12     int y;
 13     Point(int x=0,int y=0){
 14         this->x=x;
 15         this->y=y;
 16     }
 17 };
 18
 19 int n;
 20 int m;
 21 int l=0,r=0;
 22 int xa,ya,xb,yb;
 23 Point q[30000100];
 24 int dis[MAXN][MAXN];
 25 int melt[MAXN][MAXN];
 26 bool visited[MAXN][MAXN];
 27
 28 void BFS();
 29 void gch(char&);
 30 void Initialize();
 31 void SPFA(int,int);
 32
 33 int main(){
 34     Initialize();
 35     BFS();
 36     SPFA(xa,ya);
 37     printf("%d\n",dis[xb][yb]);
 38     return 0;
 39 }
 40
 41 void SPFA(int x,int y){
 42     memset(visited,0,sizeof(visited));
 43     dis[x][y]=0;
 44     q[r++]=(Point(x,y));
 45     visited[x][y]=true;
 46     while(l<r){
 47         x=q[l].x;
 48         y=q[l].y;
 49         l++;
 50         visited[x][y]=false;
 51         if(x>1&&dis[x][y]<dis[x-1][y]&&dis[x-1][y]!=melt[x-1][y]){
 52             dis[x-1][y]=std::max(dis[x][y],melt[x-1][y]);
 53             if(!visited[x-1][y]){
 54                 visited[x-1][y]=true;
 55                 q[r++]=(Point(x-1,y));
 56             }
 57         }
 58         if(x<n&&dis[x][y]<dis[x+1][y]&&dis[x+1][y]!=melt[x+1][y]){
 59             dis[x+1][y]=std::max(dis[x][y],melt[x+1][y]);
 60             if(!visited[x+1][y]){
 61                 visited[x+1][y]=true;
 62                 q[r++]=(Point(x+1,y));
 63             }
 64         }
 65         if(y>1&&dis[x][y]<dis[x][y-1]&&dis[x][y-1]!=melt[x][y-1]){
 66             dis[x][y-1]=std::max(dis[x][y],melt[x][y-1]);
 67             if(!visited[x][y-1]){
 68                 visited[x][y-1]=true;
 69                 q[r++]=(Point(x,y-1));
 70             }
 71         }
 72         if(y<m&&dis[x][y]<dis[x][y+1]&&dis[x][y+1]!=melt[x][y+1]){
 73             dis[x][y+1]=std::max(dis[x][y],melt[x][y+1]);
 74             if(!visited[x][y+1]){
 75                 visited[x][y+1]=true;
 76                 q[r++]=(Point(x,y+1));
 77             }
 78         }
 79     }
 80 }
 81
 82 void BFS(){
 83     memset(visited,0,sizeof(visited));
 84     while(l<r){
 85         int x=q[l].x;
 86         int y=q[l].y;
 87         ++l;
 88         if(x>1&&!visited[x-1][y]&&melt[x][y]+1<melt[x-1][y]){
 89             melt[x-1][y]=melt[x][y]+1;
 90             visited[x-1][y]=true;
 91             q[r++]=(Point(x-1,y));
 92         }
 93         if(x<n&&!visited[x+1][y]&&melt[x][y]+1<melt[x+1][y]){
 94             melt[x+1][y]=melt[x][y]+1;
 95             visited[x+1][y]=true;
 96             q[r++]=(Point(x+1,y));
 97         }
 98         if(y>1&&!visited[x][y-1]&&melt[x][y]+1<melt[x][y-1]){
 99             melt[x][y-1]=melt[x][y]+1;
100             visited[x][y-1]=true;
101             q[r++]=(Point(x,y-1));
102         }
103         if(y<m&&!visited[x][y+1]&&melt[x][y]+1<melt[x][y+1]){
104             melt[x][y+1]=melt[x][y]+1;
105             visited[x][y+1]=true;
106             q[r++]=(Point(x,y+1));
107         }
108     }
109 }
110
111 void Initialize(){
112     char ch;
113     memset(dis,0x3F,sizeof(dis));
114     memset(melt,0x3F,sizeof(melt));
115     scanf("%d%d",&n,&m);
116     for(int i=1;i<=n;i++){
117         for(int j=1;j<=m;j++){
118             gch(ch);
119             if(ch==‘.‘){
120                 q[r++]=(Point(i,j));
121                 melt[i][j]=0;
122                 visited[i][j]=true;
123             }
124             else if(ch==‘L‘){
125                 q[r++]=(Point(i,j));
126                 melt[i][j]=0;
127                 visited[i][j]=true;
128                 if(xa==0){
129                     xa=i;
130                     ya=j;
131                 }
132                 else{
133                     xb=i;
134                     yb=j;
135                 }
136             }
137         }
138     }
139 }
140
141 void gch(char& target){
142     do{
143         target=getchar();
144     }while(target!=‘.‘&&target!=‘X‘&&target!=‘L‘);
145 }

Backup

时间: 2025-01-08 01:06:10

[Codeup 25481] swan的相关文章

暑假集训D13总结

考试 又炸掉了= = 本来看着题就一脸茫然,默默的打暴力骗分,然后就交了卷= = 重要的是,在本机跑的毫无障碍的T3程序竟然在评测机CE啊喂,35分就没了啊喂(这可是比我现在分还高= =) 内心几近崩溃= = 题解: T1 [Codeup 25481] swan T2 [Codeup 25482 ]选美 T3 拯救莫莉斯 刷题 今天改题改的还算顺利= = 最后还帮助某byb调了一个鬼畜的判断= =(到现在都不知道为啥这个判断会炸) 被数组越界坑到死= = 博客 技术贴竟然成功破百了= =,莫名欢

[Codeup 25482] Beauty

25482: Beauty 时间限制: 1 Sec  内存限制: 128 MB献花: 7  解决: 3[献花][花圈][TK题库] 题目描述 一年一度的星哥选美又拉开了帷幕 N个人报名参加选拔,每个人都有着各自的相貌参数和身材参数(不大于10000的正整数).你的任务是尽可能让更多人被星哥选中,而唯一要求就是,在这只队伍里面的每个人,都需满足以下不等式: A (H−h)+B(W−w)≤C 其中H和W为这个人的相貌和身材,h和w为选中者中的最小相貌参数和最小身材参数,而A.B.C为三个不大于100

【codeup】1959: 全排列 及全排列算法详解

题目描述 给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列.我们假设对于小写字母有'a' < 'b' < ... < 'y' < 'z',而且给定的字符串中的字母已经按照从小到大的顺序排列. 输入 输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间. 输出 输出这个字符串的所有排列方式,每行一个排列.要求字母序比较小的排列在前面.字母序如下定义:已知S = s1s2...sk , T = t1t2...tk,则S < T 等价于,存

codeup 1918 简单计算器

问题 A: 简单计算器 时间限制: 1 Sec  内存限制: 32 MB提交: 401  解决: 192[提交][状态][讨论版][命题人:外部导入] 题目描述 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. 输入 测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔.没有非法表达式.当一行中只有0时输入结束,相应的结果不要输出. 输出 对每个测试用例输出1行,即该表达式的值,精确到小数点后2位. 样例输入 30 /

Codeup

问题 D: 习题4-4 三个整数求最大值 时间限制: 1 Sec  内存限制: 12 MB提交: 815  解决: 727[提交][状态][讨论版][命题人:外部导入] 题目描述 有3个整数a, b, c,由键盘输入,输出其中最大的数. 输入 以空格分割的三个整数. 输出 三个数中的最大值,末尾换行. 样例输入 1 3 2 样例输出 3 1 #include <stdio.h> 2 int main(){ 3 int a,b,c,max; 4 scanf("%d %d %d"

[CODEUP] 1943 进制转换

题目描述 将一个长度最多为30位数字的十进制非负整数转换为二进制数输出. 输入 多组数据,每行为一个长度不超过30位的十进制非负整数.(注意是10进制数字的个数可能有30个,而非30bits的整数) 输出 每行输出对应的二进制数. 样例输入 0 1 3 8 样例输出 0 1 11 1000 IDEA 长整数用字符串形式存储,主要解决的问题是字符串如何进行除法和余数.余数不用多说,就是最后一位余2就行.除法则应该按照平时手算除法的顺序进行,比如: for (i = 0; i < len - 1;

[codeup] 2044 神奇的口袋

题目描述 有一个神奇的口袋,总的容积是40,用这个口袋可以变出一些物品,这些物品的总体积必须是40.John现在有n个想要得到的物品,每个物品的体积分别是a1,a2--an.John可以从这些物品中选择一些,如果选出的物体的总体积是40,那么利用这个神奇的口袋,John就可以得到这些物品.现在的问题是,John有多少种不同的选择物品的方式. 输入 输入的第一行是正整数n (1 <= n <= 20),表示不同的物品的数目.接下来的n行,每行有一个1到40之间的正整数,分别给出a1,a2--an

[codeup] 1126 看电视

题目描述 暑假到了,小明终于可以开心的看电视了.但是小明喜欢的节目太多了,他希望尽量多的看到完整的节目. 现在他把他喜欢的电视节目的转播时间表给你,你能帮他合理安排吗? 输入 输入包含多组测试数据.每组输入的第一行是一个整数n(n<=100),表示小明喜欢的节目的总数. 接下来n行,每行输入两个整数si和ei(1<=i<=n),表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示. 当n=0时,输入结束. 输出 对于每组输入,输出能完整看到的电视节目的个数. 样例输入

Codeup 墓地——1814: 剩下的树

1814: 剩下的树 时间限制: 1 Sec  内存限制: 32 MB提交: 2403  解决: 928[提交][状态][讨论版][命题人:外部导入] 题目描述 有一个长度为整数L(1<=L<=10000)的马路,可以想象成数轴上长度为L的一个线段,起点是坐标原点,在每个整数坐标点有一棵树,即在0,1,2,...,L共L+1个位置上有L+1棵树.     现在要移走一些树,移走的树的区间用一对数字表示,如 100 200表示移走从100到200之间(包括端点)所有的树.     可能有M(1&