acm寒假集训第五讲总结

1.自然数的拆分问题

思路:
使用深度优先算法,用递归拆分n即可

代码:

#include <bits/stdc++.h>
using namespace std;
vector<int> a;
void f(int remain,int start,int n)
{
	int j=0;
	if(remain==0)
	{
		for(j=0;j<a.size();j++)
		{
			if(j!=a.size()-1)
			{
				cout<<a[j]<<"+";
			}
			else
			{
				cout<<a[j];
			}
		}
		cout<<endl;
		return;
	}
	for(int i=start;i<=remain&&i<n;i++)
	{
		a.push_back(i);
		f(remain-i,i,n);
		a.pop_back();
	}
}
int main()
{
	int n,i;
	cin>>n;
	f(n,1,n);
	return 0;
}

2.填涂颜色

思路:
使用深度优先搜索,从边界上的0开始搜索直到遇到1,将这些0打上标记,搜索完成后剩余的0即为所求

代码:

#include <bits/stdc++.h>
using namespace std;
int arry[32][32];
void dfs(int x,int y,int n)
{
	if(x>=n||x<0||y>=n||y<0||arry[x][y]!=0)
	{
		return;
	}
	arry[x][y]=-1;
	dfs(x+1,y,n);
	dfs(x-1,y,n);
	dfs(x,y+1,n);
	dfs(x,y-1,n);
}
int main()
{
	int n,i,j;
	cin>>n;
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			cin>>arry[i][j];
		}
	}
	for(i=0;i<n;i++)
	{
		if(arry[i][0]==0)
		{
			dfs(i,0,n);
		}
	}
	for(i=0;i<n;i++)
	{
		if(arry[i][n-1]==0)
		{
			dfs(i,n-1,n);
		}
	}
	for(j=0;j<n;j++)
	{
		if(arry[0][j]==0)
		{
			dfs(0,j,n);
		}
	}
	for(j=0;j<n;j++)
	{
		if(arry[n-1][j]==0)
		{
			dfs(n-1,j,n);
		}
	}
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
		{
			if(arry[i][j]==0)
			{
				arry[i][j]=2;
			}
			if(arry[i][j]==-1)
			{
				arry[i][j]=0;
			}
			cout<<arry[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

3.显示图像

思路:
利用广度优先算法,先将白色的点的距离记为0,其余记为可能的最大值m+n,白点加入队列,取出一个扩展,如果扩展完的点距离大于1,更新距离

代码:

#include <bits/stdc++.h>
using namespace std;
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
void bfs(vector<vector<int>>& screen,vector<vector<int>>& distance,int N,int M) 
{
    queue<pair<int, int>> q;
    for(int i=0;i<N;i++)
	{
        for(int j=0;j<M;j++) 
		{
            if(screen[i][j]==1) 
			{
                distance[i][j] = 0;
                q.push({i, j});
            }
        }
    }
    while (!q.empty()) 
	{
		pair<int,int> p=q.front();
        q.pop();
        for(int k=0;k<4;k++)
		{
            int nx=p.first+dx[k];
            int ny=p.second+dy[k];
            if (nx>=0&&nx<N&&ny>=0&&ny<M) 
			{
                if (distance[nx][ny] > distance[p.first][p.second] + 1) 
				{
                    distance[nx][ny]=distance[p.first][p.second]+1;
                    q.push({nx, ny});
                }
            }
        }
    }
}

int main()
{
    int N,M;
    cin>>N>>M; 
    vector<vector<int>> screen(N, vector<int>(M));
    vector<vector<int>> distance(N, vector<int>(M, N + M));
    char ch;
    ch=getchar();
    for(int i=0;i<N;i++) 
	{
        for(int j=0;j<M;j++) 
		{
			ch=getchar();
			if(ch=='1')
			{
				screen[i][j]=1;
			}
            if(ch=='0')
            {
            	screen[i][j]=0;
			}
        }
        ch=getchar();
    }
    bfs(screen,distance,N,M);
    for(int i=0;i<N;i++) 
	{
        for(int j=0;j<M;j++) 
		{
            cout<<distance[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

4.健康的荷斯坦奶牛 Healthy Holsteins

思路:
使用深度优先算法,得到最优解

代码:

#include <bits/stdc++.h>
using namespace std;
int v, g; 
vector<int> vitamin_needs;
vector<vector<int>> feeds; 
vector<int> selected; 
vector<int> best_feeds; 
int min_feeds = 16; 
void dfs(int index, vector<int> vitamin) 
{
    if (all_of(vitamin.begin(), vitamin.end(), [](int x) { return x <= 0; })) 
	{
        if (selected.size() < min_feeds) 
		{
            min_feeds = selected.size();
            best_feeds = selected;
        } 
		else if (selected.size() == min_feeds) 
		{
            if (selected < best_feeds) 
			{
                best_feeds = selected;
            }
        }
        return;
    }
    if (index == g || selected.size() >= min_feeds) 
	{
        return;
    }
    dfs(index + 1, vitamin);
    for (int i = 0; i < v; ++i) 
	{
        vitamin[i] -= feeds[index][i];
    }
    selected.push_back(index + 1);
    dfs(index + 1, vitamin);
    selected.pop_back();
}

int main()
{
    cin >> v;
    vitamin_needs.resize(v);
    for (int i = 0; i < v; ++i)
	{
        cin >> vitamin_needs[i];
    }
    cin >> g;
    feeds.resize(g, vector<int>(v));
    for (int i = 0; i < g; ++i) 
	{
        for (int j = 0; j < v; ++j) 
		{
            cin >> feeds[i][j];
        }
    }
    dfs(0, vitamin_needs);
    cout << min_feeds << " ";
    for (int i = 0; i < best_feeds.size(); ++i) 
	{
        cout << best_feeds[i] << (i == best_feeds.size() - 1 ? "\n" : " ");
    }
    return 0;
}

学习总结:
通过这次的学习,我学习了深度优先搜索和广度优先搜索的相关知识,通过这两种算法可以高效的搜索图或者树中的内容

posted @ 2025-02-13 22:05  asdadsdf  阅读(23)  评论(0)    收藏  举报