暑假训练第四周周报
总体情况
这一周学习了最近公共祖先,并且了解了dijkstra的模板,也在比赛中补了一些最短路的题,然后图的专题还没开始刷,这一周把搜索和搜索剪枝的专题差不多写完了,对dfs的各种代码实现更加深入了,但是搜索是一大块内容,涉及的题目多样经典。我想着后面对这些题再慢慢分个类,不然真正比赛的时候还是没有办法写出来。
联通块类的搜索
模拟战役
点击查看代码
/** - swj -
*
/>_____フ
| _ _|
/`ミ _x ノ
/ |
/ ヽ ?
/ ̄| | | |
| ( ̄ヽ__ヽ_)_)
\二つ
**/
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
#define all(v) v.begin(),v.end()
int dx[8]={0,0,1,-1,1,-1,1,-1};
int dy[8]={1,-1,0,0,1,-1,-1,1};
int m,dri;//dri为司机拥有的联通块数目
char c[10][105];//地图
bool vis[10][105];//标记
int cnt[105*105];//存齐齐每个连通块大炮的数目,因为要用来贪心
bool ck1(int x,int y)
{
return x>=1&&x<=4&&y>=1&&y<=m;
}
bool ck2(int x,int y)
{
return x>4&&x<=8&&y>=1&&y<=m;
}
//计算了司机的联通块数目,也就是一个大炮被攻击时产生的连锁反应
void bfs1(int i,int j)
{
vis[i][j]=1;
queue<pii> q;
q.push({i,j});
while(!q.empty())
{
int x=q.front().first,y=q.front().second;
q.pop();
for(int i=0;i<8;i++)
{
int nx=x+dx[i],ny=y+dy[i];
if(ck1(nx,ny)&&!vis[nx][ny]&&c[nx][ny]=='*')
{
q.push({nx,ny});
vis[nx][ny]=1;
}
}
}
}
//计算齐齐的连通块数目,和连通块数目里大炮的个数
int bfs2(int i,int j)
{
int res=0;
vis[i][j]=1;
queue<pii>q;
q.push({i,j});
while(!q.empty())
{
int x=q.front().first,y=q.front().second;
res++;//要放在这里,不然会少算
q.pop();
for(int i=0;i<8;i++)
{
int nx=x+dx[i],ny=y+dy[i];
if(ck2(nx,ny)&&!vis[nx][ny]&&c[nx][ny]=='*'){
//res++;//错了
vis[nx][ny]=1;
q.push({nx,ny});
}
}
}
return res;
}
void solve()
{
cin>>m;
for(int i=1;i<=8;i++){
for(int j=1;j<=m;j++) cin>>c[i][j];
}
for(int i=1;i<=4;i++){
for(int j=1;j<=m;j++)
{
if(c[i][j]=='*'&&!vis[i][j]) bfs1(i,j),dri++;
}
}
int p=0;
for(int i=5;i<=8;i++)
{
for(int j=1;j<=m;j++){
if(c[i][j]=='*'&&!vis[i][j]) {
cnt[++p]=bfs2(i,j);
}
}
}
/* cout<<dri<<" "<<p<<endl;
for(int i=1;i<=p;i++) cout<<cnt[i]<<" ";
cout<<endl;*/
sort(cnt+1,cnt+p+1);
if(dri>p) {
cout<<-1<<endl;
return ;
}
int ans=0;
for(int i=dri;i<=p;i++) ans+=cnt[i];
cout<<ans;
}
signed main()
{
std::ios::sync_with_stdio(0);
std::cin.tie(0);
int t=1;
//cin>>t;
while(t--)
{
solve();
}
}
三维的bfs
Jelly
点击查看代码
/** - swj -
*
/>_____フ
| _ _|
/`ミ _x ノ
/ |
/ ヽ ?
/ ̄| | | |
| ( ̄ヽ__ヽ_)_)
\二つ
**/
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
#define all(v) v.begin(),v.end()
int dx[]={0,1,0,-1,0,0};
int dy[]={1,0,-1,0,0,0};
int dz[]={0,0,0,0,1,-1};
int n;
char c[105][105][105];
bool vis[105][105][105];
int foot[105][105][105];
//三维bfs模版题
bool ck(int x,int y,int z)
{
return x>=1&&x<=n&&y>=1&&y<=n&&z>=1&&z<=n;
}
typedef struct{
int aa;
int bb;
int cc;
}three;
int ans;
int bfs(int i,int j,int k)
{
queue<three>q;
vis[i][j][k]=1;
q.push({i,j,k});
while(!q.empty())
{
int x=q.front().aa,y=q.front().bb,z=q.front().cc;
q.pop();
for(int i=0;i<6;i++)
{
int nx=x+dx[i],ny=y+dy[i],nz=z+dz[i];
if(ck(nx,ny,nz)&&!vis[nx][ny][nz]&&c[nx][ny][nz]!='*')
{
q.push({nx,ny,nz});
vis[nx][ny][nz]=1;
foot[nx][ny][nz]=foot[x][y][z]+1;
}
}
}
return foot[n][n][n];
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++) cin>>c[i][j][k];
ans= bfs(1,1,1)+1;//记得+1,虽然题目说第一个不算,但是不知道为啥+1就过了
if(ans!=1) cout<<ans;
else cout<<-1;
}
signed main()
{
std::ios::sync_with_stdio(0);
std::cin.tie(0);
int t=1;
//cin>>t;
while(t--)
{
solve();
}
}
涉及到无限的搜索
送外卖
点击查看代码
/** - swj -
*
/>_____フ
| _ _|
/`ミ _x ノ
/ |
/ ヽ ?
/ ̄| | | |
| ( ̄ヽ__ヽ_)_)
\二つ
**/
#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> pii;
#define all(v) v.begin(),v.end()
int dx[]={0,1,0,-1,0,0};
int dy[]={1,0,-1,0,0,0};
int dz[]={0,0,0,0,1,-1};
bool vis[100005],st[100005];
vector<pii>ve;
char ans[100005];
int n;
int fla;//看有没有符合的字符串
bool dfs(int x,int deep)
{
if(x<0||x>n-1) return 0;
if(x==n-1)
{
ans[deep]='\0';
return 1;
}
if(vis[x])
{
st[x]=1;
return 0;
}
vis[x]=1;
//走第一条路
if(dfs(x+ve[x].first,deep+1))
{
ans[deep]='a';
if(st[x]) fla=1;//说明在一条路径中出现了死循环
return true;
}
//走第二条路
if(dfs(x+ve[x].second,deep+1))
{
ans[deep]='b';
if(st[x]) fla=1;
return true;
}
return 0;
}
//dfs找到的结果自然就是最小的
void solve()
{
cin>>n;
vector<int>a(n),b(n);
for(auto &t:a) cin>>t;
for(auto &t:b) cin>>t;
for(int i=0;i<n;i++)
{
ve.push_back({a[i],b[i]});
}
if(dfs(0,0)){
if(fla) cout<<"Infinity!";
else cout<<ans;
}else
cout<<"No solution!";
}
signed main()
{
std::ios::sync_with_stdio(0);
std::cin.tie(0);
int t=1;
//cin>>t;
while(t--)
{
solve();
}
}
经典数独dfs
数独挑战
posted on 2024-08-11 15:36 swj2529411658 阅读(5) 评论(0) 编辑 收藏 举报