第二周冬训报告
这周开始体会到C++的便利;开始学习c++;大部分题解都是c++的算法,那样就能大概看懂题解了;
[蓝桥杯 2018 省 AB] 全球变暖|(BFS)图的广度优先搜索
题目描述
你有一张某海域 $N \times N$ 像素的照片,. 表示海洋、 # 表示陆地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中 "上下左右" 四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有 $2$ 座岛屿。
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。
例如上图中的海域未来会变成如下样子:
.......
.......
.......
.......
....#..
.......
.......
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。
输入格式
第一行包含一个整数 $N$。$(1 \le N \le 1000)$。
以下 $N$ 行 $N$ 列代表一张海域照片。
照片保证第 $1$ 行、第 $1$ 列、第 $N$ 行、第 $N$ 列的像素都是海洋。
输出格式
一个整数表示答案。
样例 #1
样例输入 #1
7
.......
.##....
.##....
....##.
..####.
...###.
.......
样例输出 #1
1
提示
时限 1 秒, 256M。蓝桥杯 2018 年第九届省赛
解析:
BFS算法:一层一层遍历完
代码:`#include<stdio.h>
char a[10000][10010];
int dx[]={1,-1,0,0},dy[]={0,0,1,-1},t,c,ans,n;//dx,dy可以更方便的判断一个点的上下左右;
void dfs(int x,int y){
if(!t){
c=0;
for(int i=0;i<4;i++){
if(a[x+dx[i]][y+dy[i]]!='.') c++;
}
if(c==4){
ans++;
t=1;//这不会被淹没,t=1,不用判断这个岛上其他的陆地,判断是否会被淹没;
}
}
a[x][y]='*';//判断过这个点就标记为*,这样就不会使主函数再判断这个岛;
for(int i=0;i<4;i++){
int xx=x+dx[i],yy=y+dy[i];
if(xx<0||xx>=n||yy>=n||a[xx][yy]!='#') continue;//只判断该岛没判断过的点,且保证不越界;
dfs(xx,yy);
}
}
int main(){
int i,j,sum=0;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%s",a[i]);
}
for(i=1;i<n-1;i++){
for(j=1;j<n-1;j++){
if(a[i][j]=='#'){
t=0;
sum++; //这是一个岛加1;
dfs(i,j); //判断这个岛是否会会被淹没,不会ansji加1;
}
}
}
printf("%d\n",sum-ans);//最后总岛减没被淹没的岛;
return 0;
}`
2,
众所周知一个程序的时间复杂度十分重要,评测机 1s
大概能做 108
次简单运算,所以根据题目所提供的数据范围你就应该精心的策划好你所写程序应该具有的时间复杂度,而在数据范围变大时,想要在时限内完成同样的一个题目,你就不得不设计出一个更快更巧妙的程序,在本题中我们认定数据范围不一样的题目不是同样的题。
现在卡夫卡有一个包含 n
个不同题目的题集A ,其中第 i
(1≤i≤n)
个题的数据范围为 10ai
,也就是说第 i
个题有 ai
个 0
,数据保证 ai
两两不同。
现在他想从题集A里面选出一些题目,然后把选出的题目后面加 9
个 0
,然后加入到一个新题集B里面,但是不能有原题,即这个题数据范围加 9
个 0
后的题不能在题集A里面有同样的题,请问卡夫卡所创造的新题集B里面最多能有多少个题。
Input
第一行包含一个整数 n (1≤n≤5×105)
— 表示题集A中的题目个数。
第二行包含 n
个整数 a1,a2,a3,...,an (1≤ai≤109)
— 表示每个题数据范围中 0
的个数,保证 n
个数互不相同。
Output
输出一行一个整数 — 表示题集B中最多能有多少个题。
解析:
本题如果暴力算法,会时限,拿另一个数组存储有的值用来遍历判断,会超内存限制;
原本学习的是C但,C++的stl更便利,最近就在学习C++;
这可以用sort先前缀排序,然后判断后面不超过9的数中是否有和前面相等的数就减1,超过9就判断下一个大的数;
代码:
`#include
using namespace std;
include
int a[1000000],n,c;
int main(){
cin>>n;
c=n;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
sort(&a[0],&a[n]);//sort的用法;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(a[i]+9==a[j]){
c--;
}
if(a[j]-a[i]>9) break;
}
}
cout<<c<<endl;
system("pause");
return 0;
}`
虽然 PHarr 喜欢听邓园长唱歌,但是没有听到自己特别喜爱的歌还是有些遗憾的。
邓园长直播间的点歌规则为「先到先服务」,即开播时观众最先点的歌会加入队列中,也可以使用钞能力。
但是作为没有经济收入的大学生的 PHarr 显然不会使用钞能力。
他知道邓园长接下来马上就要开播了,所以他决定相信自己多年单身的手速,点到自己特别喜爱的歌。
PHarr 有 n
首特别喜爱的歌,他对每首歌的喜爱程度都能用一个整数来表示,且喜爱程度各不相同,喜爱程度越大,就说明他越想点这首歌。
由于 PHarr 没有错过邓园长的每场直播,所以他知道他最想点的前 k
首歌都已经被人点过了,显然他不想浪费点歌的机会,所以他会选择第 k+1
首最想点的歌。
邓园长的直播马上就要开始了,而 PHarr 实在太过紧张,不知道自己该点的歌是哪首,所以请你帮助他尽快找到他想点的歌。
Input
第一行包含一个数字 n(1≤n≤105)
,代表有 n
首歌。
接下来 n
行,第 i
行包含一个正整数 wi(1≤wi≤109)
和一个字符串 si(1≤|si|≤15)
,代表第 i
首歌的喜爱程度和歌名。
题目保证每首歌的喜爱程度和歌名各不相同。
最后一行包含一个正整数 k(0≤k<n)
,代表已经被点过的最想点的歌的数量。
Output
输出一行,代表想点的歌的歌名。
Sample 1
Inputcopy Outputcopy
4
1 flos
3 Yellow
9 Starduster
1000000000 Kawakiwoameku
3
flos
Sample 2
Inputcopy Outputcopy
1
1000000000 CryingforRain
0
CryingforRain
解析:
用vector存储每个歌及喜爱程度;建立结构体,方便输出;
用sort排列,前k个已经被点过;v.[k]输出k+1个结构体就是应该点的歌;
代码:`#include
using namespace std;
include
include
struct song{
int x;
string a;
};
void solve(int x){
vector<pair<int,string>>v;//c++中的结构模板,定义在头文件
for(int i=0;i<x;i++){
int m;
string n;
cin>>m>>n;
v.push_back({m,n});
}
int k;
cin>>k;
sort(v.begin(),v.end(),greater<pair<int,string>>());
cout<<v[k].second<<endl;
}
int main(){
int n;
cin>>n;
solve(n);
system("pause");
return 0;
}`
浙公网安备 33010602011771号