1、题目链接:P1331 海战 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
cpp
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
char g[N][N];
int res,r,c;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
void dfs(int x,int y){
g[x][y]='.';//直接变成'.'兼顾判重
for(int i=0;i<4;i++){
int a=x+dx[i],b=y+dy[i];
if(a>0&&a<=r&&b>0&&b<=c&&g[a][b]=='#'){//合法条件
dfs(a,b);//继续搜索
}
}
}
bool check(int i,int j){
int c=0;
if(g[i][j]=='#')c++;
if(g[i+1][j]=='#')c++;
if(g[i][j+1]=='#')c++;
if(g[i+1][j+1]=='#')c++;
if(c==3)return 0;
return 1;
}//判断是否合法
int main(){
cin>>r>>c;
for(int i=1;i<=r;i++){
for(int j=1;j<=c;j++){
cin>>g[i][j];
}
}
for(int i=1;i<=r;i++){
for(int j=1;j<=c;j++){
if(i<r&&j<c&&check(i,j)==0){
printf("Bad placement.");
return 0;//不合法直接返回
}
}
}
int res=0;
for(int i=1;i<=r;i++){
for(int j=1;j<=c;j++){
if(g[i][j]=='#'){
res++;
dfs(i,j);
}
}
}
printf("There are %d ships.",res);
return 0;
}
2、题目链接:P1596 [USACO10OCT] Lake Counting S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
cpp
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int n,m;
char g[N][N];
int dx[8]={-1,-1,-1,0,1,1,1,0};//注意把方向探照灯的细节
int dy[8]={-1,0,1,1,1,0,-1,-1};
void dfs(int x,int y){
g[x][y]='.';//搜到'W'的地方全部变成'.'标记判重
for(int i=0;i<8;i++){
int a=x+dx[i],b=y+dy[i];
if(a>=0&&a<n&&b>=0&&b<m&&g[a][b]=='W')dfs(a,b);
}
}
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
scanf("%s",g[i]);//逐行读入字符串
}
int ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(g[i][j]=='W'){
ans++,dfs(i,j);
}
}
}
cout<<ans<<endl;
return 0;
}
3、题目链接:P1141 01迷宫 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
cpp
#include <bits/stdc++.h>
using namespace std;
int n,m,ans[100002],x,y,f[1002][1002];
char s[1002][1002];
void dfs(int r,int c,int z,int lll){
if (r<0 || r>=n || c<0 || c>=n || f[r][c]!=-1 || s[r][c]-'0'!=z)return;
f[r][c]=lll;ans[lll]++;
dfs(r-1,c,!z,lll);
dfs(r+1,c,!z,lll);
dfs(r,c-1,!z,lll);
dfs(r,c+1,!z,lll);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=0;i<n;i++)
scanf("%s",s[i]);
memset(f,-1,sizeof(f));
for (int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);x--;y--;
if (f[x][y]==-1)dfs(x,y,s[x][y]-'0',i);
else ans[i]=ans[f[x][y]];
}
for (int i=0;i<m;i++)
printf("%d\n",ans[i]);
return 0;
}
4、题目链接:Forgery - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
cpp
#include <bits/stdc++.h>
using namespace std;
int dx[8]={1,1,-1,-1,0,0,1,-1};
int dy[8]={1,-1,1,-1,1,-1,0,0};
int n,m;
const int N=1010;
char t[N][N];
char o[N][N];
int vis[N][N];
bool cmp(){//比较
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(t[i][j]!=o[i][j]){
return false;
}
}
}
return true;
}
void dfs(int x,int y){
int f=0;
for(int i=0;i<8;i++){
int a=x+dx[i],b=y+dy[i];
if(a<=0||a>n||b<=0||b>m||t[a][b]=='.'){//越界和.不用染色
f=1;//记录不能染色
break;//不能染色则直接跳过这个点
}
}
//染色
for(int i=0;i<8;i++){
int a=x+dx[i],b=y+dy[i];
if(!f){
o[a][b]='#';//周围染上
}
if(a<=0||a>n||b<=0||b>m||vis[a][b]){//越界和判重
continue;
}
vis[a][b]=1;
dfs(a,b);//搜索下一个点
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>t[i][j];//目标
o[i][j]='.';//原始
}
}
dfs(1,1);
string s=(cmp())?"YES":"NO";
cout<<s;
return 0;
}
5、题目链接:求细胞数量 - 洛谷
cpp
#include <bits/stdc++.h>
using namespace std;
const int N=110;
int n,m,ans=0;
int g[N][N];
int used[N][N];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
void dfs(int x,int y){
used[x][y]=1;
for(int i=0;i<4;i++){
int a=x+dx[i],b=y+dy[i];
if(g[a][b]==0||used[a][b]==1)continue;
dfs(a,b);
}
}
int main(){
cin>>n>>m;
memset(g,0,sizeof(g));
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
char c;
cin>>c;
g[i][j]=c-'0';
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(used[i][j]==0&&g[i][j]!=0){
dfs(i,j);
ans++;
}
}
}
cout<<ans;
return 0;
}
6、题目链接:UCV2013H - Slick - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
cpp
#include <iostream>
#include <cstring>
using namespace std;
const int N=110;
int n,m,g[300][300],ans,num[62501],k;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
void dfs(int x,int y){
g[x][y]=0;//直接变成海洋兼顾判重
for(int i=0;i<4;i++){
int a=x+dx[i],b=y+dy[i];
if(a>=0&&a<m&&b>=0&&b<n&&g[a][b]){
g[a][b]=0;//周围搜到的点变成海洋
k++;//当前块面积累加
dfs(a,b);
}
}
}
int main(){
while(cin>>n>>m&&n&&m){
ans=0;
memset(g,0,sizeof(g));
memset(num,0,sizeof(num));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>g[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(g[i][j]){
dfs(i,j);
ans++;//总数加一
num[k]++;
k=0;//恢复为0
}
}
}
cout<<ans<<endl;
for(int i=0;i<=62500;i++){
if(num[i]!=0){
cout<<i+1<<' '<<num[i]<<endl;//i+1因为加上中心自身的面积
}
}
}
return 0;
}
7、题目链接:P1378 油滴扩展 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
cpp
#include <bits/stdc++.h>
using namespace std;
const int maxn=10;
const double pi=3.1415926535;
bool s[maxn];//判重
double x[maxn],y[maxn],r[maxn],xa,ya,xb,yb,maxnans;
int n;
double cal(int i){//计算半径的大小
double s1=min(abs(x[i]-xa),abs(x[i]-xb));
double s2=min(abs(y[i]-ya),abs(y[i]-yb));
double ans=min(s1,s2);
for(int j=1;j<=n;j++){
if(i!=j&&s[j]){
double d=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
ans=min(ans,max(d-r[j],0.0));
}
}
return ans;
}
void dfs(int k,double sum){
if(k>n){//搜完了,取最大值返回
maxnans=max(maxnans,sum);
return;
}
for(int i=1;i<=n;i++){//遍历所有油滴
if(!s[i]){//还没被搜过
r[i]=cal(i);
s[i]=1;//标记已搜
dfs(k+1,sum+r[i]*r[i]*pi);//搜下一个,并求累加和
s[i]=0;
}
}
}
int main(){
double ss;
cin>>n;
scanf("%lf%lf%lf%lf",&xa,&ya,&xb,&yb);
ss=abs(xa-xb)*abs(ya-yb);//总面积
for(int i=1;i<=n;i++){
scanf("%lf%lf",&x[i],&y[i]);
}
dfs(1,0);//第一个点,当前总的面积是0开始深搜
printf("%d",int(ss-maxnans+0.5));
return 0;
}