p1141(01迷宫)
题目传送们
题目不难
但有很多细节要注意
首先如果每一个都去求一遍连通块
时间复杂度较高(o(n*n*m))会爆炸
于是我们就想到了拿数组记录答案
记得数组要开大一点
代码
#include<bits/stdc++.h>
using namespace std;
int n,m,id=0,p,q,num=0;
int a[1000005];
string s[1001];
bool vis[1005][1005];
int ps[1005][1005];
int dx[10]={1,-1,0,0},dy[10]={0,0,1,-1};
void dfs(int x,int y){
num++;
ps[x][y]=id;
vis[x][y]=1;
for(int i=0;i<4;i++){
int nx= x+dx[i];
int ny= y+dy[i];
if(nx >= 0 and ny >= 0 and nx < n and ny < n and s[nx][ny] != s[x][y] and vis[nx][ny] == 0){
dfs(nx,ny);
}
}
return;
}
int main(){
cin >> n >> m;
for(int i=0;i<n;i++){
cin >> s[i];
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(vis[i][j] != 1){
id++;
num=0;
dfs(i,j);
a[id]=num;
}
}
}
while(m--){
cin >> p >> q;
p--, q--;
cout << a[ps[p][q]] << endl;
}
}
p6566(观星)
题目传送门
和普通的连通块差不多
只是由于星系的原因
需要用数组存一下再按规则变化
切记(看数据范围调整数组大小)
代码:
#include<bits/stdc++.h>
using namespace std;
string s[300000];
int n,m,res=0,shixuanzhety_is=0,sb=0,pop=0;
bool vis[3000][3000];
int dx[30]={1,1,-1,-1,1,-1,0,0};
int dy[30]={-1,1,-1,1,0,0,1,-1};
int a[300000];
void dfs(int x,int y){
shixuanzhety_is++;
vis[x][y]=1;
for(int i=0;i<8;i++){
int xxx=x+dx[i];
int yyy=y+dy[i];
if(xxx > 0 and xxx <= n and yyy > 0 and yyy <= m and s[xxx][yyy] != '.' and !vis[xxx][yyy]){
dfs(xxx,yyy);
}
}
}
int main(){
cin >> n >> m;
for(int i=1;i<=n;i++){
cin >> s[i];
s[i] = " "+s[i];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(!vis[i][j] and s[i][j] != '.'){
shixuanzhety_is=0;
dfs(i,j);
a[shixuanzhety_is]++;
sb=max(shixuanzhety_is,sb);
}
}
}
for(int i=1;i<=sb;i++){
if(a[i] != 0){
res++;
pop=max(pop,i*a[i]);
}
}
cout << res << ' ' << pop << endl;
return 0;
}
p1087(FBI树)
题目传送门
此题考察的是对二叉树的应用和理解
每次用find来求当前是F,B,I 中的哪一个
先dfs()左右两个子树,再输出
若当前的字符串长度为一
则无法分2段找左右
直接输出即可
代码:
#include<bits/stdc++.h>
using namespace std;
string b;
int s;
int re=0;
void print(int o,int l){
if(o != -1 and l != -1){
cout << "F";
}else if(l != -1){
cout << "I";
}else{
cout << "B";
}
return;
}
void dfs(string x){
int xx=x.size(),l=x.find('1'),o=x.find('0');
if(xx>1){
dfs(x.substr(0,xx/2));
dfs(x.substr(xx/2));
print(o,l);
return;
}
print(o,l);
}
int main(){
cin >> s >> b;
dfs(b);
return 0;
}
p1101(单词方阵)
题目传送门
咋一看,数据范围(1000)感觉不能搜索的样子
但是这题搜到一个点后面的顺序就是固定的了
那就只有8个方向了
答案用标记数组一标记就可以了
代码:
#include<bits/stdc++.h>
using namespace std;
string b[22222],h=" yizhong";
int s,n;
bool vis[2222][2222];
int re=0;
int dx[30]={1,1,-1,-1,1,-1,0,0};
int dy[30]={-1,1,-1,1,0,0,1,-1};
void check(int x,int y,int d){
for(int i=1;i<=7;i++){
vis[x][y]=1;
x-=dx[d];
y-=dy[d];
}
return;
}
void dfs(int x,int y,int d,int cur){
if(cur == 7){
check(x,y,d);
return;
}
int xxx=x+dx[d];
int yyy=y+dy[d];
if(xxx > 0 and xxx <= n and yyy > 0 and yyy <= n and b[xxx][yyy] == h[cur+1]){
dfs(xxx,yyy,d,cur+1);
}
}
int main(){
cin >> n;
for(int i=1;i<=n;i++){
cin >> b[i];
b[i]=" "+b[i];
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(b[i][j] == 'y'){
for(int d=0;d<8;d++){
dfs(i,j,d,1);
}
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(vis[i][j]){
cout << b[i][j];
}else{
cout << '*';
}
}
cout << endl;
}
return 0;
}