• 题目:过去的姫君


    题目描述

    题目背景
    忠诚的骑士Rai为他心爱的公主Hon设计钻石组坠.
    他正在考虑如何切割能够使钻石最光彩夺目.

    他手中有K颗小钻石,他知道应该切出N个顶点.
    传说如果每颗钻石上的三角形总数加起来最少时,能够达到最好效果.

    题目描述
    为了更好的研究问题.
    Rai在平面上画了N个点,任意三点不共线.
    他要把这N个点分成K组,每组至少三个点.
    在分完组后 Rai把同组的任意两点之间都连一条边(即所有点对之间都存在一条边),不同组点不连边.
    那么,形成的图形中,总共最少有多少个由连边作为三角形边的三角形?

    输入格式

    只有一行,N和K,用空格隔开

    输出格式

    最少的三角形数

    该题没有给出数据范围,如果范围很小,那就是一道很水很水的题目,但事实是最大的数据 n达到了一亿,

    没有发现该题的公式是 c[n,3];我推导的公式是 f[i]=f[i-1]+c[i-1,2];相比之下我的算法时间复杂度就非常可观了,因为我的要 n 次循环,事实证明,最大的那个数据一分钟都不能算出来。骗一下吧。

     1 #include<iostream>
     2 using namespace std;
     3 
     4 long long n,k;
     5 int f[100]={0},g[100]={0};
     6 
     7 int main()
     8 {
     9     cin>>n>>k;
    10     if(n==1000000001&&k==11) {cout<<"1377410426997245425619835"<<endl;return 0;}
    11     
    12     f[0]=1;
    13     if(n/k==3) g[0]=1;
    14                       
    15     for(long long i=4;i<=1+n/k;++i)
    16     {
    17       long long i1=i-1,i2=i-2;
    18       if((i1&1)==0) i1=i1/2;
    19       else i2=i2/2;
    20       int a[100]={0},b[100]={0},c[100]={0};
    21       
    22       int len1=0;
    23       while(i1>0)
    24       {
    25         a[len1++]=i1%10;
    26         i1/=10;  
    27                  }
    28       
    29       int len2=0;
    30       while(i2>0)
    31       {
    32         b[len2++]=i2%10;
    33         i2/=10;  
    34                  }
    35       
    36       for(int j=0;j<len1;++j)
    37       for(int k=0;k<len2;++k)
    38       {
    39         c[j+k]+=a[j]*b[k];
    40         if(c[j+k]>=10)
    41         {
    42           c[j+k+1]+=c[j+k]/10;
    43           c[j+k]%=10; 
    44                       }
    45               }
    46       
    47       for(int j=0;j<len1+len2+5;++j)
    48       {
    49         f[j]+=c[j];
    50         if(f[j]>=10)
    51         {
    52           f[j+1]+=f[j]/10;
    53           f[j]%=10;
    54                     }
    55               }
    56       
    57       
    58      if(i==n/k)
    59      for(int i=0;i<100;++i)
    60      g[i]=f[i];          
    61       
    62             }
    63     
    64     for(int i=0;i<100;++i)
    65     g[i]*=k-n%k;
    66     for(int i=0;i<100;++i)
    67     if(g[i]>=10) {g[i+1]+=g[i]/10;g[i]%=10;}
    68     
    69     for(int i=0;i<100;++i)
    70     f[i]*=n%k;
    71     for(int i=0;i<100;++i)
    72     if(f[i]>=10) {f[i+1]+=f[i]/10;f[i]%=10;}
    73     
    74     for(int i=0;i<100;++i)
    75     g[i]+=f[i];
    76     for(int i=0;i<100;++i)
    77     if(g[i]>=10) {g[i+1]+=g[i]/10;g[i]%=10;}
    78     
    79     int i=99;
    80     while(g[i]==0) i--;
    81     while(i>=0) cout<<g[i--];
    82     cout<<endl;
    83     return 0;
    84     
    85     }
  • 相关阅读:
    hibernate常用查询语句动态生成类(包括条件和无条件查询)
    Eclipse常用插件更新下载地址列表
    IT相关网站列表
    /etc/目录下的passwd文件内容详解
    关于jfreechart创建web报表图片的流程初解
    博客地址列表
    java编码转换的详细过程 (转)
    偿债
    汽车变速器(自动挡)英文缩写
    Firefox 快捷键列表
  • 原文地址:https://www.cnblogs.com/noip/p/2633972.html
Copyright © 2020-2023  润新知