2021CCPC河南省赛欢度佳节
Posted 行码棋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021CCPC河南省赛欢度佳节相关的知识,希望对你有一定的参考价值。
- 博客主页: https://blog.csdn.net/qq_50285142
- 欢迎点赞👍收藏✨关注❤留言 📝 如有错误,敬请指正
- 🎈虽然生活很难,但我们也要一直走下去🎈
调bug调了一下午,终于调通了,真是太不容易了,以此发现自己对dfs的理解并不是很深刻,递归时某些逻辑出错(统计连通块的个数时),导致bug一时没有调出来
题目链接
思路:
可以发现一共只有17个块,我们可以把所有块的情况列举出来,一共才 2 17 = 131072 2^{17}=131072 217=131072种情况,然后再乘上17时间复杂度完全满足。所以本题就是枚举所有情况(把每个块看成01两种状态,1代表可以走,0代表不可以走),然后暴力搜索,判断所有的块是否连通
v i s [ i ] [ j ] vis[i][j] vis[i][j]表示点 ( i , j ) (i,j) (i,j)的状态
s t [ i ] [ j ] st[i][j] st[i][j]表示点 ( i , j ) (i,j) (i,j)之前是否访问过
node
中记录的是有效的点的坐标,即之前是否访问的点
cat
为连通块的个数
ans
为所有状态为1的块消除后所需要的的掷骰子的次数
cnt
为状态为1的块的个数
本题求连通块的数目容易出错(也许是我菜吧)用一个
cat
记录即可,当每次访问到可以访问的块时,就对cat
加一
#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef long long ll;
const int dx[]={-1,0,1,0};
const int dy[]={0,1,0,-1};
const int N = 1e5+5;
typedef pair<int,int>pii;
vector<pii>node;
int g[6][6];
bool vis[6][6],st[6][6];
int res,cnt,ans,cat;
void dfs(int i,int j)
{
if(!vis[i][j]) return ;
st[i][j] = true;
bool is = true;
for(int k=0;k<4;k++)
{
int nx = i + dx[k];
int ny = j + dy[k];
if(nx<1 or nx>5 or ny<1 or ny>5) continue;
if(vis[nx][ny] && !st[nx][ny])
{
cat += 1;
is = false;
st[nx][ny] = true;
dfs(nx,ny);
}
}
}
void solve()
{
int all;
res = 0;
cin>>g[1][1]>>g[1][2]>>g[1][4]>>g[1][5];
cin>>g[2][2]>>g[2][3]>>g[2][4];
cin>>g[3][2]>>g[3][3]>>g[3][4];
cin>>g[4][2]>>g[4][3]>>g[4][4];
cin>>g[5][1]>>g[5][2]>>g[5][4]>>g[5][5];
cin>>all;
for(int i=0;i<(1<<17);i++)
{
cnt = 0,ans = 0,cat = 0;
memset(vis,false,sizeof vis);
memset(st,false,sizeof st);
for(int j=0;j<17;j++)
{
if((i>>j)&1)
{
vis[node[j].fi][node[j].se] = true,cnt++;
ans += (g[node[j].fi][node[j].se]+5)/6;
}
}
if(vis[5][1]) cat = 1;
dfs(5,1);
if(cat==cnt and ans<=all)
res = max(res,cnt);
}
cout<<res<<'\\n';
}
int main()
{
for(int i=1;i<=5;i++)
for(int j=1;j<=5;j++)
{
if(i==1 and j==3) continue;
if(i==2 and j==1) continue;
if(i==2 and j==5) continue;
if(i==3 and j==1) continue;
if(i==3 and j==5) continue;
if(i==4 and j==1) continue;
if(i==4 and j==5) continue;
if(i==5 and j==3) continue;
node.push_back({i,j});
}
int _;
cin>>_;
while(_--)
{
solve();
}
return 0;
}
往期优质文章推荐
以上是关于2021CCPC河南省赛欢度佳节的主要内容,如果未能解决你的问题,请参考以下文章
CCPC河南省赛-C|树状数组dfs序上处理子树问题 + 离散化