洛谷 P6582 【座位调查】
这道题就两个步骤:
1.找联通块个数:判断是否符合标准并且找联通块个数
我用的广搜实现的,思路挺简单的:
先找一个联通块的端点,根据题中的定义,一个联通块的端点,周围所不是座位的个数(指上下左右),只有3个,或者4个(只有一个点的情况),对这个点进行搜索,标记,然后扩展,遇到下一个座位,就走,走过就标记,并对联通块计数的加一,最后返回走的联通块的座位数。
那么,如何判断这不是正确的教室呢? 因为我们对搜过的都进行了标记,所以我们可以判断有没有是座位却没有被标记的情况,因为只有有端点的才能是符合标准的,没有对这一块进行搜索,那就是没有端点,也就不符合了。又因为我们从端点开始搜索的,那就说明每一个点能扩展的点,就只有一个点(本来应该是两个的,但是因为前一个点被标记了,也不能走,相当于只能扩展一个),我们可以进行统计每一个点能扩展的点,如果大于1,就也是错的。
2.对方法数目进行计算:利用乘法原理
啊本人不会画图就手打了吧
对于这一块的话OOOOOOO ,第一个可以填k个学校,那么后面一个就只能填k-1学校,后面的也是,以此类推,可以得到每一个联通块的方法数目为: k*(s-1)^(k-1) ,其中size为联通块大小,然后对于所有联通块一起的方法书,也一样,全乘起来就okk。
剩下的细节之类的都在代码里面了,码代上上代码:
#include <bits/stdc++.h>
using namespace std;
long long dx[] = {1 , 0 , -1 , 0} , dy[] = {0 , -1 , 0 , 1}; //上下移动
long long n , m , k , sum , p = 998244353; //sum是联通块个数
long long s[1000010]; //存储每一个联通块的大小
char a[1010][1010]; //存储图
bool f; //判断是否座位只联通一个座位
bool vis[1010][1010]; //标记
struct node{
long long c , d;
};
long long ksm(long long x , long long y){ //快速幂,怕超时,没去试pow(x,y)会不会超时
long long ret = 1;
y %= p;
x %= p;
while(y){
if(y % 2 == 1){
ret = ret * x;
ret %= p;
}
x = x % p * x % p;
x %= p;
y /= 2;
}
return ret;
}
long long pd(long long x , long long y){ //统计周围不是座位的个数
long long sssum = 0;
if(a[x + 1][y] != 'O') sssum++;
if(a[x - 1][y] != 'O') sssum++;
if(a[x][y + 1] != 'O') sssum++;
if(a[x][y - 1] != 'O') sssum++;
return sssum;
}
long long bfs(long long x , long long y){ //广搜
long long t = 1;
queue<node> q;
node nod;
nod.c = x;
nod.d = y;
q.push(nod);
node now;
vis[x][y] = 1;
while(!q.empty()){
now = q.front();
q.pop();
long long tt = 0;
for(int v = 0; v <= 3; v++){
int nx = now.c + dx[v] , ny = now.d + dy[v];
if(!vis[nx][ny] && a[nx][ny] == 'O'){
tt++; //统计这个点能扩展的点的个数
t++;
vis[nx][ny] = 1;
nod.c = nx;
nod.d = ny;
q.push(nod);
}
}
if(tt > 1){ //大于一个就说明不符合要求,并且不能用不等于,因为最后一个点是不能扩展的,就是0,但是合法
f = true;
return 0; //不符合直接返回
}
}
return t;
}
int main(){
cin >> n >> m >> k;
for(int i = 1; i <= n + 5; i++)
for(int j = 1; j <= m + 5; j++) a[i][j] = 'X'; //初始化
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) cin >> a[i][j];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++){
if(a[i][j] == 'O' && !vis[i][j]){ //找端点。为什么有vis?因为一个联通块有两个端点我们只需要搜索一次就OK
int ha = pd(i , j);
if(ha < 3) continue; //不是端点
f = false;
sum++; //块数加一
s[sum] = bfs(i , j);
if(f){ //不符合条件
cout << 0;
return 0;
}
}
}
for(int i = 1; i <= n; i++) //找没搜过却是座位的情况,也是错误的
for(int j = 1; j <= m; j++)
if(a[i][j] == 'O' && !vis[i][j]){
cout << 0;
return 0;
}
long long ans = 1;
k %= p;
for(int i = 1; i <= sum; i++){
ans *= k % p * ksm((k - 1) , s[i] - 1) % p; //记得每一次都mod一下,不然会只有30分的,别问我怎么知道的,调了半天的
ans %= p;
}
cout << ans % p;
return 0;
}
/*
7 7 99
XOOXOOO
XOXXXXO
XOOXOXO
XXXXOXO
XOOXOOO
XXOXXXX
XOOXOOO
*/
啊就这么多了,一道不错的搜索题
洛谷 P6582 【座位调查】的更多相关文章
- 洛谷P1386座位安排
座位安排 今天,在机房里做了这道题目,我来整理一下思路. 首先读懂题意,这n个人是不需要按1到n来一次安排的,也就是说你可以先安排任意一个人. 那么有一种很好排除的情况,那就是对于大于等于i的作为的需 ...
- 洛谷——P2071 座位安排 seat.cpp/c/pas
P2071 座位安排 seat.cpp/c/pas 题目背景 公元二零一四年四月十七日,小明参加了省赛,在一路上,他遇到了许多问题,请你帮他解决. 题目描述 已知车上有N排座位,有N*2个人参加省赛, ...
- 【二分图】【最大匹配】【匈牙利算法】洛谷 P2071 座位安排 seat.cpp/c/pas
∵每个座位可以坐俩人,所以拆点最大匹配. #include<cstdio> #include<vector> #include<cstring> using nam ...
- 洛谷P2071 座位安排
题目背景 公元二零一四年四月十七日,小明参加了省赛,在一路上,他遇到了许多问题,请你帮他解决. 题目描述 已知车上有N排座位,有N*2个人参加省赛,每排座位只能坐两人,且每个人都有自己想坐的排数,问最 ...
- 洛谷 P2071 座位安排 seat.cpp/c/pas
P2071 座位安排 seat.cpp/c/pas 题目背景 公元二零一四年四月十七日,小明参加了省赛,在一路上,他遇到了许多问题,请你帮他解决. 题目描述 已知车上有N排座位,有N*2个人参加省赛, ...
- 洛谷P1407 工资
洛谷P1407 工资 本题地址:http://www.luogu.org/problem/show?pid=1407 题目描述 有一家世界级大企业,他们经过调查,发现了一个奇特的现象,竟然在自己的公司 ...
- 【洛谷1607】【USACO09FEB】庙会班车
题面 题目描述 逛逛集市,兑兑奖品,看看节目对农夫约翰来说不算什么,可是他的奶牛们非常缺乏锻炼--如果要逛完一整天的集市,他们一定会筋疲力尽的.所以为了让奶牛们也能愉快地逛集市,约翰准备让奶牛们在集市 ...
- 洛谷 P2835 刻录光盘
题目链接 https://www.luogu.org/problemnew/show/P2835 题目描述 在JSOI2005夏令营快要结束的时候,很多营员提出来要把整个夏令营期间的资料刻录成一张光盘 ...
- 洛谷NOIp热身赛题解
洛谷NOIp热身赛题解 A 最大差值 简单树状数组,维护区间和.区间平方和,方差按照给的公式算就行了 #include<bits/stdc++.h> #define il inline # ...
随机推荐
- Java实现 LeetCode 542 01 矩阵(暴力大法,正反便利)
542. 01 矩阵 给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离. 两个相邻元素间的距离为 1 . 示例 1: 输入: 0 0 0 0 1 0 0 0 0 输出: 0 0 0 ...
- Java实现 蓝桥杯 算法提高 复数四则运算
算法提高 6-17复数四则运算 时间限制:1.0s 内存限制:512.0MB 提交此题 设计复数库,实现基本的复数加减乘除运算. 输入时只需分别键入实部和虚部,以空格分割,两个复数之间用运算符分隔:输 ...
- Java实现 LeetCode 206 反转链表
206. 反转链表 反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL ...
- Java实现 蓝桥杯 基因牛的繁殖
基因牛的繁殖 张教授采用基因干预技术成功培养出一头母牛,三年后,这头母牛每年会生出1头母牛, 生出来的母牛三年后,又可以每年生出一头母牛.如此循环下去,请问张教授n年后有多少头母牛? 以下程序模拟了这 ...
- 解Bug之路-记一次存储故障的排查过程
解Bug之路-记一次存储故障的排查过程 高可用真是一丝细节都不得马虎.平时跑的好好的系统,在相应硬件出现故障时就会引发出潜在的Bug.偏偏这些故障在应用层的表现稀奇古怪,很难让人联想到是硬件出了问题, ...
- docker-compose mysql和node连接认证mongo问题
前言 最近,想部署一个自己的项目,鉴于自己的服务器是VPS(虚拟主机),配置也不够,就想到了用 docker 直接部署好了,这样既方便部署也方便不用的时候卸载或更新 然后本地搭建了环境,踩了一些坑,在 ...
- javascript内置函数提供的显式绑定
内置函数提供的显式绑定 最近在开发中遇到使用arr.map(module.fun) 这样的写法时(在一个模块调用了另外一个模块的方法), 造成了函数中this丢失的问题, 显示为undefined, ...
- Redis之分布式锁实现
点赞再看,养成习惯,微信搜索[三太子敖丙]关注这个互联网苟且偷生的工具人. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的 ...
- 1.Redis Lock
使用场景 同步锁,让业务方法在锁设定的时间内是同步执行的 redisService.setIfAbsent redisService.expire @PostMapping("/update ...
- Centos7 systemctl添加自定义系统开机服务
Centos7的服务systemctl脚本存放在: /usr/lib/systemd/ 有系统(system)和用户(user)之分,需要开机不登陆就能运行的程序,存下系统服务里,即:/usr/lib ...