zoukankan      html  css  js  c++  java
  • ZROI2018提高day1t1

    传送门

    分析

    在考场上我通过画图发现了对于n个点肯定用一个六边形围起来最优(假装四边形是特殊的六边形),我们发现可以将这个六边形分成两个梯形(梯形的高可以为0),然后我们便枚举两个梯形共同的底边和它们分别的高。代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    const int inf = 2e9+7;
    int main(){
          int n,m,i,j,k;
          for(n=1;n<=50;n++){
              int ans=inf;
              int h1,h2,w;
              for(h1=0;h1<=n;h1++)
                for(h2=0;h2<=n;h2++)
                  for(w=1;w<=n;w++)
                    if(h1*(2*w-h1+1)+h2*(2*w-h2+1)-2*w>=2*n)
                      ans=min(ans,2*w+h1+h2+2);
              printf("%d
    ",ans);
          }
          return 0;
    }

    通过这个代码我们可以打出一张表,大致如下:

    6
    8  9  10 11 12 12
    13 14 14 15 15 16 16 17 17 18 18 18
    19 19 20 20 20 21 21 21 22 22 22 23 23 23 24 24 24 24

    于是我们发现每一行的个数分别为1,6,2*6,3*6......,而所有的数都是连续的,对于第i行这一行第一个数有i-2个,最后一个数有i个,其余的数每个均有i-1个。这样我们便可以求出n在哪一行然后暴力搞了。由于总行数最多有√n个,而每一行的数也很少,所以在找到这个规律之后直接搞就行了。注意特判n=1的情况。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    const int inf = 2e9+7;
    int Ans[110000];
    int main(){
          int n,m,i,j=1,k;
          scanf("%d",&n);
          if(n==1){
              puts("6");
              return 0;
          }
          for(i=1;i<=20000;i++)
              if(3*i*(i-1)+1>=n){
                k=i;
                break;
              }
          int la=(k-1)*6+1;
          if(k==2)la=8;
          n-=(1+3*(k-1)*(k-2));
          for(i=1;i<=max(k-2,1);i++)
            Ans[i]=la;
          la++;
          int sum=0;
          for(i=max(k-2,1)+1;i<=(k-1)*6-k;i++){
              sum++;
              if(sum==k)sum=1,la++;
              Ans[i]=la;
          }
          la++;
          for(i=(k-1)*6-k+1;i<=(k-1)*6;i++)Ans[i]=la;
          printf("%d
    ",Ans[n]);
          return 0;
    }
  • 相关阅读:
    LeetCode 227. Basic Calculator II
    LeetCode 224. Basic Calculator
    LeetCode 103. Binary Tree Zigzag Level Order Traversal
    LeetCode 102. Binary Tree Level Order Traversal
    LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode 105. Construct Binary Tree from Preorder and Inorder Traversal
    LeetCode 169. Majority Element
    LeetCode 145. Binary Tree Postorder Traversal
    LeetCode 94. Binary Tree Inorder Traversal
    LeetCode 144. Binary Tree Preorder Traversal
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9551749.html
Copyright © 2011-2022 走看看