Given a satellite image of some sea region, your task is to count:
1. The number of islands in this region
2. The number of islands having different area in this region
3. The number of islands having different shape in this region
The image is illustrated as below. Sea is represented by "." and land is represented by '#'. An island consists of all connected land in 4 (up, down, left and right) directions.
.####.. .....#. ####.#. .....#. ..##.#.
There are 4 islands in the image above. Three of them have an area of 4 and one has an area of 2, so the number of islands having different area is 2. Two of them share the same shape "####" so the number of islands having different shape is 3.
InputThe first line contains 2 integers N and M (1 ≤ N, M ≤ 50).
Then follows an N * M matrix which is the image of the sea region.
OutputOutput 3 numbers which are the number of islands, the number of islands having different area and the number of islands having different shape in this region.
Sample Input
5 7 .####.. .....#. ####.#. .....#. ..##.#.
Sample Output
4 2 3
这个题是当时蓝桥杯模拟的最后一道题
#include <iostream> #include<bits/stdc++.h> using namespace std; #define INF 0x3f3f3f const int N = 55; char mapp[N][N]; bool isvis[N][N]; vector<int>G[N*N]; int minn[N*N]; int n,m; int ind; const int mv[4][2]= {{-1,0},{1,0},{0,-1},{0,1}}; void dfs(int x,int y) { isvis[x][y]=true; //标记已访问 G[ind].push_back(x*n+y); //记录当前联通块坐标 minn[ind]=min(minn[ind],x*n+y); //当前联通块中的最小坐标 for(int i=0; i<4; i++) //四个方向 { int xi=x+mv[i][0]; int yi=y+mv[i][1]; if(xi<0||xi>=n||yi<0||yi>=m||isvis[xi][yi])continue; //不成立 dfs(xi,yi); } } void solve() { for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { if(!isvis[i][j]) //遇到一个联通块 { G[ind].clear(); dfs(i,j); ind++; } } } set<int> size; set<vector<int> > area; for(int i=0; i<ind; i++) //图像移至原点 { for(int j=0; j<(int)G[i].size(); j++) G[i][j]-=minn[i]; } for(int i=0; i<ind; i++) { size.insert(G[i].size()); //块大小 area.insert(G[i]); //块内容 } cout<<ind<<" "<<size.size()<<" "<<area.size()<<endl; } int main() { while(scanf("%d%d%*c",&n,&m)!=EOF) { memset(isvis,false,sizeof(isvis)); memset(minn,INF,sizeof(minn)); ind=0; for(int i=0; i<n; i++) { gets(mapp[i]); for(int j=0; j<m; j++) { if(mapp[i][j]=='.') isvis[i][j]=true; } } solve(); } return 0; }
现据密探所报,公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用*表示,平地用.表示。骑士们一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那骑士们就会被撞死。骑士们在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。
Input输入的第一行C表示共有C个测试数据,每个测试数据的前一行有三个整数N,M,T。 N,M迷宫的大小N*M(1 <= N,M <=10)。T如上所意。接下去的前N*M表示迷宫的第一层的布置情况,后N*M表示迷宫第二层的布置情况。Output如果骑士们能够在T时刻能找到公主就输出“YES”,否则输出“NO”。Sample Input
1 5 5 14 S*#*. .#... ..... ****. ...#. ..*.P #.*.. ***.. ...*. *.#..
Sample Output
YES
这个题相比于普通的搜索而言多了传送门,加一维度判断就行
#include <iostream> #include<stdio.h> #include<bits/stdc++.h> using namespace std; char maze[2][35][35]; int vis[2][35][35]; int flag; int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}}; int n,m,t; struct node { int x; int y; int z; int step; }ft,now; queue<node>que; bool judge() { if(ft.x<0||ft.x>=n||ft.y<0||ft.y>=m) return 0; if(vis[ft.z][ft.x][ft.y]==1) return 0; if(maze[ft.z][ft.x][ft.y]=='#'&&maze[!ft.z][ft.x][ft.y]=='*') return 0; if(maze[ft.z][ft.x][ft.y]=='*') return 0; if(maze[ft.z][ft.x][ft.y]=='#'&&maze[!ft.z][ft.x][ft.y]=='#') return 0; return 1; } void bfs() { ft.x=0,ft.y=0,ft.z=0,ft.step=0; while(!que.empty())que.pop(); que.push(ft); vis[0][0][0]=1; while(!que.empty()) { now=que.front(); que.pop(); if(now.step>t) return ; if(maze[now.z][now.x][now.y]=='P') { flag=1; cout<<"YES"<<endl; return ; } for(int i=0;i<4;i++) { ft.x=now.x+dir[i][0]; ft.y=now.y+dir[i][1]; ft.z=now.z; if(judge()) { if(maze[ft.z][ft.x][ft.y]=='#') { vis[ft.z][ft.x][ft.y]=1; ft.z=!ft.z; } ft.step=now.step+1; que.push(ft); vis[ft.z][ft.x][ft.y]=1; } } } } int main() { int c,i; cin>>c; while(c--) { cin>>n>>m>>t; memset(vis,0,sizeof vis); memset(maze,'*',sizeof maze); for(i=0;i<n;i++) scanf("%s",&maze[0][i]); for(i=0;i<n;i++) scanf("%s",&maze[1][i]); flag=0; bfs(); if(!flag) cout<<"NO"<<endl; } return 0; }
Post offices will be built in some, but not necessarily all of the villages. A village and the post office in it have the same position. For building the post offices, their positions should be chosen so that the total sum of all distances between each village and its nearest post office is minimum.
You are to write a program which, given the positions of the villages and the number of post offices, computes the least possible sum of all distances between each village and its nearest post office.
Input
Output
Sample Input
10 5 1 2 3 6 7 9 11 22 44 50
Sample Output
9
-
dis[i][j]表示i,j之间建一个邮局的最小距离和
-
dp[i][j]表示前i个村庄建j个邮局的最小距离和
- N个村庄建P个邮局,相当于每个邮局均有一个作用范围,该邮局位于其作用范围的中间位置,就是要找到一个k,使前k个村庄建P - 1个邮局,最后几个村庄建一个邮局的方案满足题意。
#include <iostream> #include<string.h> using namespace std; #define inf 0x3f3f3f int dp[1005][1005]; int a[305]; int dis[305][305]; int main() { int n,m,i,j,k; cin>>n>>m; for(i=1;i<=n;i++) cin>>a[i]; for(i=1;i<=n-1;i++) { for(j=i+1;j<=n;j++) { dis[i][j]=dis[i][j-1]+a[j]-a[(i+j)/2]; } } memset(dp,inf,sizeof(dp)); for(i=1;i<=n;i++) { dp[i][1]=dis[1][i]; } for(i=2;i<=m;i++) { for(j=i;j<=n;j++) { for(k=i-1;k<=j-1;k++) { dp[j][i]=min(dp[j][i],dp[k][i-1]+dis[k+1][j]); } } } cout<<dp[n][m]<<endl; return 0; }