专栏文章
题解:P13556 【MX-X15-T3】画圈圈
P13556题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mioiusim
- 此快照首次捕获于
- 2025/12/02 19:55 3 个月前
- 此快照最后确认于
- 2025/12/02 19:55 3 个月前
题目大意
多组数据.
数据给定一个 和一个 。 生成一个长宽为 的表格,将其中每组满足 的格子 圈起来。该表格同时使得其中的连通块数量 。 求出满足条件的 , 中 的最小值。
解题
零分 做法
看到这个联通块,我就想到了用搜索做
思路: 用 广搜 (bfs) 寻找未涂色区域,但会 TLE !
连一个点都骗不到分 qwq
CPP思路: 用 广搜 (bfs) 寻找未涂色区域,但会 TLE !
#include<bits/stdc++.h>
using namespace std;
const int MAX = 1000;
bool color[MAX][MAX],v[MAX][MAX];
int dx[4] = {-1, 1, 0, 0},dy[4] = {0, 0, -1, 1};
int count(int n, int m, int k) {
memset(color, false, sizeof(color));memset(v, false, sizeof(v));//清空
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if ((i + j) % k == 0) {color[i][j] = true;/*涂色*/}
}
}
int x = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (!color[i][j] && !v[i][j]) {
x++;int queue[MAX*MAX][2],front = 0,p = 0;
//bfs
queue[p][0]=i;
queue[p][1]=j;
p++;v[i][j] = true;
while(front<p){
int x=queue[front][0],y=queue[front][1];front++;
for (int d = 0; d < 4; d++) {
int nx=x+dx[d];
int ny=y+dy[d];
if(nx>=1&&nx<=n&&ny >=1&&ny<=m&&!color[nx][ny]&&!v[nx][ny]) {
v[nx][ny]=true;
queue[p][0]=nx;queue[p][1]=ny;p++;
}
}
}
}
}
}
return x;
}
//寻找n+m最小值
int find(int k, int l) {
if (l == 1) {return 1;}
for (int sum=2;sum<=100;sum++) {
for (int n=1;n<=sum/2;n++) {
int m=sum-n,x=count(n,m,k);
if (m<1) continue;
if (x>=l) {return sum;}
}
}
return -1;
}
int main() {
int t,k,l;cin>>t;
while(t--){cin>>k>>l;cout<<find(k,l)<<endl;}
}
满分 做法
可以发现:
当 时,
当 时,
若矩形高为 时 最优. 例子:
: ■□■□□■□□■□□■......
得出最少格子数为 .
即 , .再看一个例子:
: ■□■□□□■□□□■□□□■......
最少格子数还是为 .得出 最小就是 .解释一下:
一定是画圈(黑)的,
所以 .
从 开始每一段是 个 ■ 和 个 □,一共 个方块,
所以要 乘 .
当 时:
CPP若矩形高和宽接近时 最优
可以用二分求解
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main(){
ll t,k,l;cin>>t;
while(t--){
cin>>k>>l;
if (k==2){//k=2是特殊情况,用二分求解
ll L=1,R=10000000000;
while(L<R){
ll mid=(L+R)/2,x;x=mid/2;
if(x*(mid-x)>=2*l){R=mid;}else{L=mid+1;}
}
cout<<L<<"\n";
}else{//使用公式
if (l==1) cout<<"2\n";
else{cout<<(l-1)*k+1<<"\n";}
}
}
}
公式解题
我们也可以想想 时的公式
CPP不难发现:
当 时, 最小值为 .推出过程:
每 2x2 个方块有 2 个白块
每 2x3 个方块有 3 个白块
.....白块数量( )总是
可以得出 .
n+m 最小值就会是 .
简化一下就是 .
当然,记得向下取整
得出公式 .
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main(){
ll t,k,l;cin>>t;
while(t--){
cin>>k>>l;
if (k==2){
cout<<ceil(sqrt(8*l))<<"\n";//使用新公式
}else{//使用公式
if (l==1) cout<<"2\n";
else{cout<<(l-1)*k+1<<"\n";}
}
}
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...