【模拟】【杂题】jzoj 6345. 【NOIP2019模拟2019.9.8】ZYB建围墙
稍微有点巧妙的找规律题。
其实这道题如果一个一个填是很难找出规律的,有意思的是,它可以一条一条的填。
我们假设现在有一个数n,我们可以直接算出n能够做成的最大的实心正六边形房子群,多余的数字,我们以正六边形的边长x为一个单位去填补它。
设一个值表示此次填补可以增加多少个能放房子的空位。
对于这个值,我们发现每六次填补有这样变化的规律:
x+1,x,x,x,x,x-1.
那么可以先处理出最大的实心正六边形,那么对于包围这个形状所需要的围墙长度是已知的,再加上填补新增的空位,就得到了我们需要的答案。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e6+10; 4 int n; 5 int main(){ 6 // freopen("wall.in","r",stdin); 7 // freopen("wall.out","w",stdout); 8 scanf("%d",&n); 9 for(int i=1;;i++){ 10 if(i*(i-1)*3+1==n){ 11 printf("%d",i*6); 12 return 0; 13 } 14 if(i*(i+1)*3+1>n){ 15 int num=i*(i-1)*3+1,ans=i*6; 16 if(num+i-1>=n){ 17 printf("%d",ans+1); 18 return 0; 19 } 20 else num+=i-1; 21 if(num+i>=n){ 22 printf("%d",ans+2); 23 return 0; 24 } 25 else num+=i; 26 if(num+i>=n){ 27 printf("%d",ans+3); 28 return 0; 29 } 30 else num+=i; 31 if(num+i>=n){ 32 printf("%d",ans+4); 33 return 0; 34 } 35 else num+=i; 36 if(num+i>=n){ 37 printf("%d",ans+5); 38 return 0; 39 } 40 else num+=i; 41 if(num+i+1>=n){ 42 printf("%d",ans+6); 43 return 0; 44 } 45 else num+=i+1; 46 } 47 } 48 }
总之也可以先算出前40个,然后画图找找规律。
以上。
——抓住了时间,却不会利用的人,终究也逃不过失败的命运。