dfs
dfs
1.P2036

#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
int n;
ll s[12];
ll k[12];
ll ans=1e9;
void dfs(int dep,ll suan,ll ku,int cnt){
if(dep==n+1){
if(cnt==0){//没有取配料,保证至少取一种配料
return;
}
ll a= abs(suan-ku);
ans=min(ans,a);
return;
}
// cout<<"hi";
dfs(dep+1,suan*s[dep],ku+k[dep],cnt+1);//当前配料取
dfs(dep+1,suan,ku,cnt);//当前配料不取
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>s[i]>>k[i];
}
dfs(1,1,0,0);
cout<<ans;
return 0;
}
//这个题不适合动态规划
2.P1605 迷宫

#include<bits/stdc++.h>
using namespace std;
int n,m,t;
int ans;
int sx,sy,fx,fy;
int path[8][8];
bool st[8][8];//是否经过
int dx[4]={-1,1,0,0};//上下左右 (行)
int dy[4]={0,0,-1,1};//(列)
void dfs(int x,int y){
if(x==fx&&y==fy){
ans++;
}
for(int i=0;i<4;i++){
int bx=x+dx[i];
int by=y+dy[i];
if(st[bx][by]||bx<1||bx>n||by<1||by>m||path[bx][by]==1){
continue;
}
st[bx][by]=true;
dfs(bx,by);
st[bx][by]=false;
}
}
int main(){
cin>>n>>m>>t;//n行m列t个障碍
cin>>sx>>sy;//起点
cin>>fx>>fy;//终点
int x,y;
while(t--) {
cin>>x>>y;
path[x][y]=1;//1表示有障碍
}
st[sx][sy]=true;
dfs(sx,sy);
cout<<ans;
return 0;
}
注意:
易错点是起点一定是最开始就经过了,所以要true(防止后续再走,原题要求每个点最多只能走一次)
st[sx][sy]=true;
P2404 自然数的拆分

#include<bits/stdc++.h>
using namespace std;
int n;
string ans;
void dfs(int s,int pre){//pre指的是上一位的数字,目的是要使得输出每一位递增(或相等)
if(s==n){
cout<<ans<<endl;
}
for(int i=1;i<n;i++){
if(i<pre)continue;
if(s+i>n)continue;
pre=i;
if(!ans.empty()){
ans+='+';
ans+=i+'0';
}
else{
ans+=i+'0';
}
dfs(s+i,pre);
if(ans.size()==1) ans.erase(ans.size()-1,1);
else{
ans.erase(ans.size()-2,2);
}
}
}
int main(){
cin>>n;
dfs(0,0);
return 0;
}
P1101 单词方阵


完整代码
#include<bits/stdc++.h>
using namespace std;
//利用结构体数组记录yizhong所经历的位置
struct node{
int x;//行
int y;//列
}path[110];
//方向向量
int dx[8]={-1,-1,0,1,1,1,0,-1};//行
int dy[8]={0,1,1,1,0,-1,-1,-1};//列
int n;
string s="yizhong";
const int N=110;
char g[N][N];//原字符串方阵
bool vis[N][N];//是否在yizhong里
void dfs(int a,int b,int dep,int fx,node path[]){
if(dep==7){//递归出口
for(int i=0;i<7;i++){
vis[path[i].x][path[i].y]=true;
}
return;
}
//下一个点
int bx=a+dx[fx];
int by=b+dy[fx];
if(dep==6||g[bx][by]==s[dep+1]) {
// vis[x][y]=true;要走完整个yizhong才可以确定整个路径上的字母是true的
//放入路径
path[dep].x=a;
path[dep].y=b;
dfs(bx,by,dep+1,fx,path);
}
}
int main() {
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>g[i][j];
}
}
//做dfs
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(g[i][j]=='y'){
//起点必须是y
//考虑选择哪一方向延伸,因为同一单词的摆放不能变方向
for(int k=0;k<8;k++) {
int x=i+dx[k];
int y=j+dy[k];
if(g[x][y]=='i'){//如果第二位是i,说明这个方向可能可以
dfs(i,j,0,k,path) ;//起点是(i,j)方向是沿着k然后进行dfs
}
}
}
}
}
//输出答案
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(vis[i][j]){//如果在yizhong里面的话
cout<<g[i][j];
}
else{
cout<<'*';
}
}
cout<<endl;
}
return 0;
}
P1162 填涂颜色


80分代码
错误原因:每个点仅考虑一个方向一直走(如p1101思想)

p1596 lake counting

解析:
关键是理解题意
题目是说计算水坑数量
一个W会和他八个方向上如果有水都会合并,然后不断往外扩散合并
合并后算一个水坑
所以本题就是对每个W进行dfs将他周围W合并算出一个水坑,看一共多少个水坑
答案
//分析:就是一个w的八个方向上的水都算成一个水坑
//所以用dfs
#include<bits/stdc++.h>
using namespace std;
const int N=110;
char g[N][N];
int n,m;
int ans;
int dx[8]={-1,-1,0,1,1,1,0,-1};//行
int dy[8]={0,1,1,1,0,-1,-1,-1};//列
void dfs(int a,int b){
g[a][b]='.';//遍历过这个水
for(int i=0;i<8;i++) {
int bx=a+dx[i];
int by=b+dy[i];
if(bx>=0&&bx<n&&by>=0&&by<m&&g[bx][by]=='W'){//合并,继续dfs
dfs(bx,by);
}
}
return ;//递归出口 ,当不满足上面条件就会退出dfs,dfs要有return(即递归出口)防止会死循环了!
}
int main() {
cin>>n>>m;
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]=='W'){
dfs(i,j);//对这个水dfs,将他周围的水合并
ans++;
}
}
}
cout<<ans;
return 0;
}
完整代码
//分析:就是一个w的八个方向上的水都算成一个水坑
//所以用dfs
#include<bits/stdc++.h>
using namespace std;
const int N=110;
char g[N][N];
int n,m;
int ans;
int dx[8]={-1,-1,0,1,1,1,0,-1};//行
int dy[8]={0,1,1,1,0,-1,-1,-1};//列
void dfs(int a,int b){
g[a][b]='.';//遍历过这个水
for(int i=0;i<8;i++) {
int bx=a+dx[i];
int by=b+dy[i];
if(bx>=0&&bx<n&&by>=0&&by<m&&g[bx][by]=='W'){//合并,继续dfs
dfs(bx,by);
}
}
return ;//递归出口
}
int main() {
cin>>n>>m;
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]=='W'){
dfs(i,j);//对这个水dfs,将他周围的水合并
ans++;
}
}
}
cout<<ans;
return 0;
}

浙公网安备 33010602011771号