• YYHSOI模拟赛题解(T6围栏问题)


      

    题目描述

    在一片草原上,有n只兔子无忧无虑地生活着。这片草原可以划分成m×m的方阵。每个方格内最多有一只兔子。

    一位饲养员负责喂养这些兔子。为了方便,她需要用篱笆建造最多k座围栏,将草原上的兔子全部围起来。

    围栏需要满足以下条件:

    (1)必须沿着网格线建造;

    (2)每座围栏是一个不与自身重叠或相交的封闭回路;

    (3)各座围栏之间互相不重叠、不相交;

    (4)一座围栏不能被围在另一座围栏里面。

    请你帮助饲养员计算一下围栏总长度的最小值。

    输入

    输入文件名为fence.in

    输入第1行为三个整数mkn

    接下来n行每行为一对正整数xy,表示第x行第y列的方格中有一只兔子。

    输出

    输出文件名为fence.out

    输出仅1行,为一个正整数,表示围栏总长度的最小值。

    样例输入

    【输入输出样例1】
    fence.in
    6 1 4
    1 3
    4 2
    4 4
    6 4
    fence.out
    18

    样例输出

    【输入输出样例2】
    fence.in
    6 2 4
    1 3
    4 2
    4 4
    6 4
    fence.out
    16
     

    【数据范围】


    对于10%的数据,k=1;


    对于10%~30%的数据,k=2;


    对于30%~60%的数据,n≤10;


    对于100%的数据,1≤k≤n≤16,m≤1,000。

     

    这道题题解表示可以用Dancing Links X做,但是我不会。

    但是我们会看到这个数据范围只有16,那么我们对于每一只兔子,我们都可以暴力枚举它是自己建一个围栏,还是使用之前的围栏。当然我们还可以求证出一些非常奇妙的东西。比如说:矩形去围一定是最优的,就算你不用矩形去围,我们也可以将它化成一个周长相同,但是面积更大的矩形。这样子还可以围更多的兔子何乐而不为呢?

    当我们决定要自建一个栅栏时,灰常的简单。如果我们要插入一个围栏怎么办?同样灰常的简单,我们将这个围栏拆了,加入这个点后重新建一遍围栏就行了。

      1 #include <cmath>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <iostream>
      5 #include <algorithm>
      6 
      7 using namespace std;
      8 
      9 struct node
     10 {
     11     long long X,Y;    
     12 };
     13 
     14 int N;
     15 long long L,R;
     16 long long RR[1000005];
     17 node a[1000005];
     18 long long s[1000005];
     19 long long AnsA,AnsB;
     20 
     21 void gbsort1(int l,int r)
     22 {
     23     int mid=(l+r)/2;
     24     if (l == r) return;
     25     gbsort1(l,mid);
     26     gbsort1(mid+1,r);
     27     int head1=l;
     28     int tail1=mid;
     29     int head2=mid+1;
     30     int tail2=r;
     31     int len=head1-1;
     32     while (head1 <= tail1 && head2 <= tail2)
     33     {
     34         if (a[head1].X < a[head2].X)
     35         {
     36             RR[++len]=a[head1].X;
     37             head1++;
     38         }
     39         else if (a[head1].X >= a[head2].X)
     40         {
     41             RR[++len]=a[head2].X;
     42             head2++;
     43             AnsA+=(tail1-head1+1);
     44         }
     45     }
     46     while (head1 <= tail1)
     47     {
     48         RR[++len]=a[head1].X;
     49         head1++;
     50     }
     51     while (head2 <= tail2)
     52     {
     53         RR[++len]=a[head2].X;
     54         head2++;
     55     }
     56     for (int i=l; i<=r; i++)
     57     {
     58         a[i].X=RR[i];
     59     }
     60 }
     61 
     62 void gbsort2(int l,int r)
     63 {
     64     int mid=(l+r)/2;
     65     if (l == r) return;
     66     gbsort2(l,mid);
     67     gbsort2(mid+1,r);
     68     int head1=l;
     69     int tail1=mid;
     70     int head2=mid+1;
     71     int tail2=r;
     72     int len=head1-1;
     73     while (head1 <= tail1 && head2 <= tail2)
     74     {
     75         if (a[head1].Y <= a[head2].Y)
     76         {
     77             RR[++len]=a[head1].Y;
     78             head1++;
     79         }
     80         else if (a[head1].Y > a[head2].Y)
     81         {
     82             RR[++len]=a[head2].Y;
     83             head2++;
     84             AnsB+=(tail1-head1+1);
     85         }
     86     }
     87     while (head1 <= tail1)
     88     {
     89         RR[++len]=a[head1].Y;
     90         head1++;
     91     }
     92     while (head2 <= tail2)
     93     {
     94         RR[++len]=a[head2].Y;
     95         head2++;
     96     }
     97     for (int i=l; i<=r; i++)
     98     {
     99         a[i].Y=RR[i];
    100     }
    101 }
    102 
    103 long long gcd(long long a,long long b)
    104 {
    105     if (b == 0) return a;
    106     else return gcd(b,a % b);
    107 }
    108 
    109 int main()
    110 {
    111     scanf("%d%lld%lld",&N,&L,&R);
    112     for (int i=1; i<=N; i++)
    113     {
    114         int X;
    115         scanf("%d",&X);
    116         s[i]=s[i-1]+X;
    117         a[i].X=L * i - s[i];
    118         a[i].Y=R * i - s[i];
    119     }
    120     AnsA=0; AnsB=0;
    121     gbsort1(0,N);
    122     gbsort2(0,N);
    123     //printf("%lld %lld\n",AnsA,AnsB);想· 
    124     long long Tmp=(long long) N;
    125     Tmp=Tmp * (Tmp + 1) / 2;
    126     long long Ans=AnsA-AnsB;
    127     if (Ans == Tmp)
    128     {
    129         printf("1\n");
    130     }
    131     else if (Ans == 0)
    132     {
    133         printf("0\n");
    134     }
    135     else
    136     {
    137         long long D=gcd(Ans,Tmp);
    138         printf("%lld/%lld\n",Ans/D,Tmp/D);
    139     }
    140     return 0;
    141 }
    Show My Ugly Code
  • 相关阅读:
    未能加载包“Microsoft SQL Server Data Tools”
    SharePoint 客户端对象模型共用ClientContext的坑
    安装VisualStudio 2015 x64 中文企业版失败
    Could not load file or assembly 'Microsoft.SqlServer.Management.Sdk.Sfc, Version=11.0.0.0 系统找不到指定的文件。
    为Sharepoint 2010 批量创建SharePoint测试用户
    User Profile Service Application 配置同步连接时,报 MOSS MA not found
    SharePoint 2010 系统账户没完全控制权限了
    百度编辑器 UEditor 报错汇总
    更改SharePoint 2007/2010/2013 Web 应用程序端口号
    SharePoint 2013 报:网站在改进过程中处于只读状态,对此给您带来的不便,我们深表歉意
  • 原文地址:https://www.cnblogs.com/TUncleWangT/p/7064908.html
Copyright © 2020-2023  润新知