蓝桥杯 1.下棋的贝贝 困难 知识点:枚举 ,模拟,矩阵

112 阅读4分钟

1.下棋的贝贝【算法赛】 - 蓝桥云课 (lanqiao.cn)

我们按照贪心的思想,逆时针进行放置棋子(当然顺时针也可以),获得的增益最大:

image.png

因为按照矩形放置棋子,上下左右的邻居都可以获得增益:

image.png

内圈

首先外圈不一定可以铺满,也不知道会铺到哪里去,但是内圈一定是铺满的,我们先算内圈的贡献和,再看还剩多少可以铺外圈。

首先我们用给定的n,对其就平方根得出内圈边长m:

假设n是18,那么肯定是有一个4*4的正方形,再进行延伸得到的:

4*4的正方形就是内圈,多余的2个铺到外圈:

image.png 当我们求出内圈边长m之后: image.png 我们发现内圈的4个角的地方只能接触2个面:

image.png 因此这四个角的贡献我们可以用(m2)(m2)4(m-2)*(m-2)*4来表示:(m-2)*(m-2)是内圈1角的面积,*4是因为有4个角:

image.png

除了四个角剩下的地方每个可以接触三个面,一共有4个:

image.png 我们把圆球减去,发现每条边就变为m-1了:

image.png

因此我们可以用(m-1)*4 * 3-4来表示:即由4个m-1的组成,每个接触3条边,减去4个球。

然后内圈排完了,看有没有剩的,有剩的我们接着外圈继续排。还是拿18举例,18可以变为一个基础的4*4矩阵,但是肯定还有剩余的,因为4 * 4=16,外圈还要再排两个。

外圈排第一个的时候只能接触到1个面,如紫色球部分:

image.png

第二个第三个第四个……都可以贡献到2个面,如红色球部分:

image.png

直到第m个,我们发现又只能贡献1个面了:紫色球部分:

image.png

我们发现四个角(紫球)都只能接触一个面,而其他部分(红球)则可以接触两个面。

外圈

因此我们需要考虑四种1情况:

第一种情况,没有排到第二个角:

image.png

对于这种情况,我们只需要把特例减掉,即紫色球部分(只接触一个面,则只有两个贡献),红球部分接触两个面,有4个贡献。

我们用 2+(x-1)*4 表示,其中2是特例(紫球)贡献的(接触一个面2个贡献), x-1就是把特列(紫球)减掉,再乘上4个贡献(红球部分,接触两个面)

第二种情况,排到第二个角:

image.png 这时就有两个特例了(两个紫球):

加上这两个特例的贡献:2*2=4
再减去这两个特例:x-2
乘剩下的贡献(红球):4

所以公式为:4+(x-2)*4

第三种情况,排到第三个角:

image.png 此时有3个特例,我们

加上3个特例的贡献:2*3=6
减去3个特例:x-3
乘剩下部分(红球,接触两个面)的贡献:*4

总结公式为:6+(x-3)*4

第四种情况,排到第四个角:

image.png 此时4个特例:

加上4个特例的贡献:2*4=8
减去4个特例: x-4
乘其他部分(红球)的贡献:*(2*2)

code

n最大1e18,一定要开long long

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
  int n=0;cin>>n;
  //特殊情况,只有1个没有邻居
  if(n==1)
{
cout<<0;
return 0; 
}
  int m=sqrt(n);  //求内圈边长


  //内圈
  int sum=(m-2)*(m-2)*4+(m-1)*4*3-4;  //内圈的贡献
  int x=n-m*m;  //看还有多少剩余的要在外圈排
  m++;  //新的外围边长,内圈边长+1

//外圈
if(x)  //如果有剩余的
{
   if(x<=m-1)  //如果没走到第二个角
   {
      sum+=2+(x-1)*4; //接触面为1的紫球的贡献 +( 减去一个紫球得到的接触面为2的红球的个数*其贡献值)
   }
   else if(x<=2*m-1) //如果走到了第二个角
   {
      sum+=4+(x-2)*4;  //接触面为1的2个紫球的贡献 +( 减去2个紫球得到的接触面为2的红球的个数*其贡献值)
   }
   else if(x<=3*m-1) //如果走到了第三个角
   {
      sum+=6+(x-3)*4;  //接触面为1的3个紫球的贡献 +( 减去2个紫球得到的接触面为2的红球的个数*其贡献值)
   }
   else if(x<=4*m-1)  //如果走到第四个角
   {
      sum+8+(x-4)*4;   //接触面为1的4个紫球的贡献 +( 减去4个紫球得到的接触面为2的红球的个数*其贡献值)
   }
  
} cout<<sum;
  return 0;
}

image.png