White roses, red blood, a|

Chillturtle

园龄:4个月粉丝:0关注:0

ZYB建围墙 题解

ZYB建围墙

题意

给你一个数 n,求把这 n 个格子围起来所需的格子数的最小值。

思路

首先,我们尝试把图画出来枚举前面来找出规律。下面这张图里是 1~10 的距离。

好的,我们可以发现。在这个图中 7 这个图内部是六边形。外面一圈绿色的也是六边形。这个时候我们发现数据中有一部分是这么写的:

N=6×k×(k+1)2+1

于是,我们考虑从这里入手。首先我们再次进行枚举可知,当 n=7 时需要 12 个。当 n=19 时需要 18 个。好的规律已经出来了。当 k 为整数的时候,我们可以得到当前的答案为 6×(k+1)

在这个基础上,我们考虑进行扩展。当现在是一个六边形的时候。设现在的边长为 edge 那么每扩展 6 层就有能多围出来的量就为:e1,eeeee+1。那么我们就直接枚举接近 n 的一个满足内外都为六边形的状态。暴力一层层加到 n 就可以了。这里需要枚举的量很小。所以时间复杂度大致就为:O(n)

AC code

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace WYL{
	const int INF=1e9;
	const int N=1e3+10;
	int n,opt=0;
	int now=1,y=1,sy,x=6;
	int f[N]={0,6,8,9,10,11,12,12,13,14,14,15,15,16,16,17,17,18,18,18,19};
	bool check(int k){
		for(int i=1;i*i<=INF;i++){
			if(n==6*(i*(i+1)/2)+1){
				opt=i;
				return true;
			}
		}
		return false;
	}
	signed main(){
		cin>>n;
		if(check(n)){
			cout<<6*(opt+1)<<endl;
			return 0;
		}else{
			while(now+x<=n){
				now+=x;
				y++;
				x+=6;
			}
			sy=n-now;
//			cout<<sy<<" "<<y<<endl;
			if(sy==0){
//				cout<<"***"<<endl;
				cout<<x<<endl;
			}else{
//				cout<<x<<endl;
				cout<<x+(sy/y)+1<<endl;
			}
		}
		return 0;
	}	
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//	freopen("wall.in","r",stdin);
//	freopen("wall.out","w",stdout);
	WYL::main();
	return 0;	
}

本文作者:Chillturtle

本文链接:https://www.cnblogs.com/OluMel/p/18473229

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Chillturtle  阅读(9)  评论(0编辑  收藏  举报
//雪花飘落效果 html { cursor: url('https://files.cnblogs.com/files/yyyzyyyz/%E6%8C%87%E9%92%88.ico'), auto; }
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起