课后作业-2025年11月16号作业
题目:P1451 求细胞数量
网址:https://www.luogu.com.cn/problem/P1451
思路:不为0的地方就是细胞,然后dfs搜连通块,把搜到的都标记一下,保证不重复。
知识点:dfs
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+100;string str[maxn];
int n,m;
bool vis[maxn][maxn];
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
void dfs(int x,int y)
{vis[x][y]=1;for(int i=0;i<=3;i++){int xx=x+dx[i],yy=y+dy[i];if(xx>=1&&xx<=n&&yy>=1&&yy<=m){if(str[xx][yy]!='0'&&!vis[xx][yy]){dfs(xx,yy);}}}
}
int main(){cin>>n>>m;int ans=0;for(int i=1;i<=n;i++){cin>>str[i];str[i]=" "+str[i]; } bool ok=true;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(str[i][j]!='0'&&!vis[i][j]){ans++;dfs(i,j);}}}cout<<ans; return 0;
}
题目:P1331 海战
网址:https://www.luogu.com.cn/problem/P1331
思路:为#的地方就是船,然后dfs搜连通块,把搜到的都标记一下,保证不重复。题目说船一定是方形的,所有我们还要判断一下是否合法。
知识点:dfs,简单思维
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e3+100;string str[maxn];
int n,m,cnt=0,mn_x,mx_x,mn_y,mx_y;
bool vis[maxn][maxn];
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
void dfs(int x,int y)
{vis[x][y]=1;cnt++;mn_x=min(mn_x,x);mx_x=max(mx_x,x);mn_y=min(mn_y,y);mx_y=max(mx_y,y); for(int i=0;i<=3;i++){int xx=x+dx[i],yy=y+dy[i];if(xx>=1&&xx<=n&&yy>=1&&yy<=m){if(str[xx][yy]=='#'&&!vis[xx][yy]){dfs(xx,yy);}}}
}
int main(){cin>>n>>m;int ans=0;for(int i=1;i<=n;i++){cin>>str[i];str[i]=" "+str[i]; } bool ok=true;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(str[i][j]=='#'&&!vis[i][j]){ans++;mn_x=i;mx_x=i;mn_y=j;mx_y=j;cnt=0; dfs(i,j);if(cnt!=(mx_x-mn_x+1)*(mx_y-mn_y+1)){ok=false;break;} }}if(!ok)break;}if(!ok)cout<<"Bad placement."; else cout<<"There are "+to_string(ans)+" ships.";return 0;
}
题目:P1460 [USACO2.1] 健康的荷斯坦奶牛 Healthy Holsteins
网址:https://www.luogu.com.cn/problem/P1460
思路:按照题目意思进行搜索,每种要么选,要么不选。搜索完之后我们判断一下是否满足最小量这个条件,同时更新一下答案。
知识点:dfs,字典序
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e2+100;int v,g;
int need[maxn],a[maxn][maxn];
vector<int> ans;
void dfs(int id,vector<int> s)
{if(id>g){int b[v+1]={0};for(auto it:s){int x=it;for(int j=1;j<=v;j++)b[j]+=a[x][j];} for(int i=1;i<=v;i++){if(b[i]<need[i])return;}if(ans.size()==0||s.size()<ans.size()||(s.size()==ans.size()&&s<ans))ans=s;return;}s.emplace_back(id);dfs(id+1,s);s.pop_back();dfs(id+1,s);
}
int main(){cin>>v;for(int i=1;i<=v;i++){cin>>need[i];} cin>>g;for(int i=1;i<=g;i++){for(int j=1;j<=v;j++){cin>>a[i][j];}}vector<int>v;dfs(1,v);cout<<ans.size()<<" ";for(auto it:ans)cout<<it<<" "; return 0;
}
题目:P1506 拯救oibh总部
网址:https://www.luogu.com.cn/problem/P1506
思路:从(0,0)上下左右搜索染色,遇到障碍或者越界就回溯,最后会发现未被染色的非障碍的点就是被障碍保护的地区,最后遍历全地图寻找此类点数目即可。
知识点:dfs
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e2+100;int n,m;
int vis[maxn][maxn];
string str[maxn];
int dx[]={1,-1,0,0};
int dy[]={0,0,1,-1};
void dfs(int x,int y)
{vis[x][y]=1;for(int i=0;i<=3;i++){int xx=x+dx[i],yy=y+dy[i];if(xx<0||xx>n+1||yy<0||yy>m+1||vis[xx][yy]==1)continue;dfs(xx,yy);}
}
int main(){cin>>n>>m;for(int i=1;i<=n;i++){cin>>str[i];str[i]=" "+str[i]; } for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(str[i][j]=='*')vis[i][j]=1;}}dfs(0,0);int ans=0;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(!vis[i][j])ans++;}}cout<<ans;return 0;
}
题目:P1036 [NOIP 2002 普及组] 选数
网址:https://www.luogu.com.cn/problem/P1036
思路:考虑使用 DFS。递归生成所有可能的组合。id 表示当前选择的起始位置,s表示当前组合的和,cnt 表示已经选择的数的个数。对于每一种组合,计算它们的和,并判断这个和是否是素数。如果和是素数,那么答案加一。
知识点:dfs
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e2+100;int a[maxn],n,ans,k;
bool check(int x)
{if(x<2)return false;for(int i=2;i*i<=x;i++){if(x%i==0)return false;}return true;
}
void dfs(int id,int cnt,int s)
{if(id>n){if(cnt==k&&check(s))ans++;return;}dfs(id+1,cnt,s);if(cnt+1<=k)dfs(id+1,cnt+1,s+a[id]);
}
int main(){cin>>n>>k;for(int i=1;i<=n;i++){cin>>a[i]; } dfs(1,0,0);cout<<ans; return 0;
}
