P1671 Rigging the Bovine Election S
网页链接
P1671 Rigging the Bovine Election S 
题目描述
农场被划分为
5
×
5
5\\times 5
5×5 的格子,每个格子中都有一头奶牛,并且只有荷斯坦(标记为 H)和杰西(标记为 J)两个品种。如果一头奶牛在另一头上下左右四个格子中的任一格里,我们说它们相连。奶牛要大选了。现在杰西奶牛们想选择
7
7
7 头相连的奶牛,划成一个竞选区,使得其中它们品种的奶牛比荷斯坦的多。
要求你编写一个程序求出方案总数。
输入格式
5
5
5 行,表示农场的情况。
输出格式
输出划区方案总数。
输入输出样例 #1
输入 #1
HHHHH
JHJHJ
HHHHH
HJHHJ
HHHHH
输出 #1
2
解题思路
本题是组合枚举 + 连通性检查的搜索题。农场为
5
×
5
5\\times5
5×5 的网格,共
25
25
25 个格子,需要从中选出
7
7
7 个格子组成一个竞选区,要求这
7
7
7 个格子连通,并且其中杰西奶牛(J)的数量不少于
4
4
4。由于
25
25
25 选
7
7
7 的组合数只有
C
25
7
=
480700
C_{25}^7 = 480700
C257=480700,可以直接枚举所有组合并逐一检验。
1. 问题等价转化
- 将
5
×
5
5\\times5
5×5 网格编号为1
∼
25
1\\sim25
1∼25,每个编号对应一个坐标(
行
,
列
)
(行,列)
(行,列)。 - 从
25
25
25 个编号中选出7
7
7 个,相当于枚举所有7
7
7 个位置的组合。 - 对于每个组合,需要判断:
- 这
7
7
7 个格子是否构成一个连通块(通过上下左右相邻关系); - 其中字符为 J 的格子数量是否
≥
4
\\ge 4
≥4。
- 这
- 满足上述条件的组合计数即为答案。
2. 算法实现
5
×
5
5\\times5
5×5 的字符矩阵 mp。
- 使用递归函数 dfs2(x, y) 枚举递增组合,避免重复。x 表示当前可选的起始编号,y 表示正在选择第几个格子。
- 选择编号
i
i
i 后,将其映射为坐标 (c[y], d[y]),其中行 c[y] = (i+4)/5,列 d[y] = i – (行-1)*5。 - 当 y == 7 时,表示已选满
7
7
7 个格子,进入检查流程。
- 统计这
7
7
7 个格子中字符为 J 的个数 sum。 - 若 sum < 4,直接跳过。
- 否则以第一个格子为起点,使用 dfs1(k) 从该点出发,只沿已选中的格子进行上下左右搜索,统计连通块大小 t。
- 若 t == 7,说明这
7
7
7 个格子全部连通,方案数 ans++。
3. 复杂度分析
- 时间复杂度:枚举
C
25
7
≈
4.8
×
10
5
C_{25}^7 \\approx 4.8\\times10^5
C257≈4.8×105 个组合,每个组合检查连通性最多访问7
7
7 个格子和它们的4
4
4 个邻居,操作次数很小,总时间完全在限制内。 - 空间复杂度:仅需存储地图、当前组合的坐标数组、访问标记数组等,均为常数级或
O
(
7
)
O(7)
O(7)。
总结
利用
25
25
25 格选
7
7
7 格组合数较小的特点,直接枚举所有可能的格子组合,并通过 DFS 检查连通性和品种数量条件。方法简单直观,足以在时限内求出方案总数。
代码内容
#include <bits/stdc++.h>
using namespace std;
#define endl '\\n'
typedef long long ll;
typedef unsigned long long ull;
typedef vector<vector<ll>> vvt;
typedef pair<ll,ll> pll;
const ll N=1e3+10;
const ll INF=1e18;
const ll M=1e6+10;
const ll mod=1e9+7;
const ll r=7;
const ll f[4][2]={{1,0},{0,1},{–1,0},{0,–1}};
char mp[8][8];
ll ans,t,c[8],d[8],vis[8];
void dfs1(ll k)
{
vis[k]=1; t++;
for(ll i=0;i<4;i++)
{
ll nx=c[k]+f[i][0];
ll ny=d[k]+f[i][1];
for(ll j=1;j<=r;j++)
if(c[j]==nx && d[j]==ny && !vis[j]) dfs1(j);
}
}
void dfs2(ll x,ll y)
{
if(y==r+1)
{
ll sum=0; t=0;
memset(vis,0,sizeof(vis));
for(ll i=1;i<=r;i++) if(mp[c[i]][d[i]]=='J') sum++;
dfs1(1);
if(sum>=4 && t==r) ans++;
return;
}
if(x>25) return;
for(ll i=x;i<=25;i++)
{
c[y]=(i+4)/5;
d[y]=i–((i+4)/5–1)*5;
dfs2(i+1,y+1);
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
for(ll i=1;i<=5;i++)
for(ll j=1;j<=5;j++)
cin>>mp[i][j];
dfs2(1,1);
cout<<ans<<endl;
return 0;
}
网硕互联帮助中心







评论前必须登录!
注册