• NOIP2014-10-30模拟赛


    T1:逗比三角形

    【题目描述】

    J是一名OI退役滚粗文化课选手,他十分喜欢做题,尤其是裸题。他现在有一个二维盒子和一些二维三角形,这个盒子拥有无限的高度和L的宽度。而且他的三角形也都是一些锐角三角形或者是直角三角形。现在小J想把这些三角形放入盒子里,由于小J从txt大神犇那里学会了魔法,所以小J的三角形既可以无视盒子边界又可以重叠放置,但是必须有一条边紧贴盒子底面所在的直线。

    现在小J想要最大化在盒子中的被三角形覆盖的区域的面积(即三角形间的重叠部分只算一遍),请问这个最大值应该是多少?

    【输入格式】

    一行一个整数T,代表数据组数。下面T部分,每部分第一行两个整数N,L分别代表三角形数量与盒子的宽度。下面N行每行三个整数ai,bi,ci表示三角形i的三条边长。

    【输出格式】

    T行,每行一个实数代表盒子内部被三角形覆盖的区域的面积的最大值。

    T2:数三角形

    Description

    给定一个nxm的网格,请计算三点都在格点上的三角形共有多少个。下图为4×4的网格上的一个三角形。

    注意三角形的三点不能共线。

    Input

    输入一行,包含两个空格分隔的正整数m和n。

    Output

    输出一个正整数,为所求三角形数量。

    Sample Input


    2 2

    Sample Output

    76

    数据范围
    1<=m,n<=1000

    T3:树上三角形

    Description

    给定一大小为n的有点权树,每次询问一对点(u,v),问是否能在u到v的简单路径上取三个点权,以这三个权值为边长构成一个三角形。同时还支持单点修改。

    Input

    第一行两个整数n、q表示树的点数和操作数
    第二行n个整数表示n个点的点权
    以下n-1行,每行2个整数a、b,表示a是b的父亲(以1为根的情况下)
    以下q行,每行3个整数t、a、b
    若t=0,则询问(a,b)
    若t=1,则将点a的点权修改为b

    Output

    对每个询问输出一行表示答案,“Y”表示有解,“N”表示无解。

    Sample Input

    5 5
    1 2 3 4 5
    1 2
    2 3
    3 4
    1 5
    0 1 3
    0 4 5
    1 1 4
    0 2 5
    0 2 3

    Sample Output

    N
    Y
    Y
    N

    HINT

    对于100%的数据,n,q<=100000,点权范围[1,2^31-1]

    附加题:同名"数三角形"

    Description

    在一只大灰狼偷偷潜入Farmer Don的牛群被群牛发现后,贝西现在不得不履行着她站岗的职责。从她的守卫塔向下瞭望简直就是一件烦透了的事情。她决定做一些开发智力的小练习,防止她睡着了。想象牧场是一个X,Y平面的网格。她将N只奶牛标记为1…N (1 <= N <= 100,000),每只奶牛的坐标为X_i,Y_i (-100,000 <= X_i <= 100,000;-100,000 <= Y_i <= 100,000; 1 <= i <=N)。然后她脑海里想象着所有可能由奶牛构成的三角形。如果一个三角形完全包含了原点(0,0),那么她称这个三角形为“黄金三角形”。原点不会落在任何一对奶牛的连线上。另外,不会有奶牛在原点。给出奶牛的坐标,计算出有多少个“黄金三角形”。顺便解释一下样例,考虑五只牛,坐标分别为(-5,0), (0,2), (11,2), (-11,-6), (11,-5)。下图是由贝西视角所绘出的图示。 

    Input

    第一行:一个整数: N 第2到第N+1行: 每行两个整数X_i,Y_i,表示每只牛的坐标

    Output

    * 第一行: 一行包括一个整数,表示“黄金三角形的数量”

    Sample Input

    5
    -5 0
    0 2
    11 2
    -11 -6
    11 -5

    Sample Output

    5

    T1:
    对于一个三角形,可以用微积分的思想把它看成许多线段,然后最大面积肯定就是线段又大到小地把宽度排满
    由于线段长度是连续的,不是离散的,所以最后如果线段最小值为k,那么高度大于等于k的部分一定会被选
    放到一个三角形中,高度大于等于k的部分也对应一个宽度,把所有的宽度加起来如果正好等于L的话,那么一定就是最优解。
    由于存在EPS,我们可以用二分答案
     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #define MAXN 100005
     7 #define EPS 1e-5
     8 using namespace std;
     9 double a[MAXN],b[MAXN],c[MAXN];
    10 double S[MAXN],H[MAXN];
    11 int n;
    12 double LL;
    13 bool cal(double h){
    14     double ret=0;
    15     for(int i=1;i<=n;i++){
    16         if(H[i]>h){
    17             ret+=(H[i]-h)*a[i]/H[i];
    18         }
    19     }
    20     return (ret<=LL);
    21 }
    22 void solve(){
    23     scanf("%d%lf",&n,&LL);
    24     for(int i=1;i<=n;i++){
    25         scanf("%lf%lf%lf",&a[i],&b[i],&c[i]);
    26         if(b[i]>c[i]){
    27             swap(b[i],c[i]);
    28         }
    29         if(a[i]>b[i]){
    30             swap(a[i],b[i]);
    31         }
    32         double p=(a[i]+b[i]+c[i])/2.0;
    33         S[i]=sqrt(p*(p-a[i])*(p-b[i])*(p-c[i]));
    34         H[i]=S[i]*2/a[i];
    35     }
    36     double L=0,R=1000000;
    37     double mid;
    38     while(L+EPS<R){
    39         mid=(L+R)/2.0;
    40         if(cal(mid)){
    41             R=mid;
    42         }
    43         else{
    44             L=mid;
    45         }
    46     }
    47     double ans=0;
    48     for(int i=1;i<=n;i++){
    49         if(H[i]>L){
    50             ans+=(H[i]-L)*a[i]/H[i]*(H[i]-L)/2.0;
    51         }
    52     }
    53     ans+=L*LL;
    54     printf("%.6f
    ",ans);
    55     
    56 }
    57 int main()
    58 {
    59     freopen("sbtg10.in","r",stdin);
    60     freopen("sbtg.out","w",stdout);
    61     int T;
    62     scanf("%d",&T);
    63     for(int i=1;i<=T;i++){
    64         solve();
    65     }
    66     return 0;
    67 }
    Code1

    T2:

    用组合数学的知识,先把所有的情况算出来,然后减去共线的情况即可

    注意斜的用gcd算,不能用组合数了

    还有就是注意不重不漏
     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define MAXN 1005005
     6 #define ll long long
     7 using namespace std;
     8 ll C[MAXN][4];
     9 int g[1005][1005];
    10 int Gcd(int x,int y){
    11     if(g[x][y]){
    12         return g[x][y];
    13     }
    14     return g[x][y]=((y==0)?x:Gcd(y,x%y));
    15 }
    16 void make(){
    17     for(int i=0;i<MAXN;i++){
    18         C[i][0]=1;
    19     }
    20     for(int i=1;i<MAXN;i++){
    21         for(int j=1;j<=3;j++){
    22             C[i][j]=C[i-1][j]+C[i-1][j-1];
    23         }
    24     }
    25 }
    26 int n,m;
    27 int main()
    28 {
    29     make();
    30     ll ans=0;
    31     scanf("%d%d",&n,&m);
    32     n++;m++;
    33     ans+=C[n*m][3];
    34     ans-=C[n][3]*m;
    35     ans-=C[m][3]*n;
    36     ///!!!
    37     for(int i=2;i<=m;i++){
    38         for(int j=2;j<=n;j++){
    39             int t=Gcd(i-1,j-1)-1;
    40             ans-=t*(m-i+1)*(n-j+1)*2;
    41         }
    42     }
    43     printf("%lld
    ",ans);
    44     return 0;
    45 } 
    Code2

    T3:

    这题好坑啊

    设树链上的节点为a1,a2,a3,……,an

    排一下序发现:

    如果存在ai+ai+1>ai+2 那么就可以构成三角形了

    即较小的两条边大于最大的边

    然后考虑一下,如果出题目的人很变态,故意想卡你,使得这个数列尽可能多,但偏偏构成不了三角形(QAQ)

    那么肯定是1 1 2 3 5 8 13 ……

    斐波拉契数列,然后第50项就炸int了,由于数据又在int范围内,所以当节点数目超过50个时,再想卡你也卡不了,一定可以构成三角形

    对于小于50的,直接暴力即可

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define MAXN 100005
     6 #define ll long long
     7 using namespace std;
     8 int v[MAXN];
     9 int first[MAXN],Next[MAXN*2],to[MAXN*2],cnt;
    10 int dep[MAXN],fa[MAXN];
    11 int q[MAXN],top;
    12 //double edge
    13 int read(){
    14     int ret=0;
    15     char c=getchar();
    16     do{
    17         ret=ret*10+c-'0';
    18         c=getchar();
    19     }while('0'<=c&&c<='9');
    20     return ret;
    21 }
    22 void Add(int x,int y){
    23     Next[++cnt]=first[x];first[x]=cnt;to[cnt]=y;
    24     Next[++cnt]=first[y];first[y]=cnt;to[cnt]=x;
    25 }
    26 int n;
    27 void dfs(int x){
    28     for(int e=first[x];e;e=Next[e]){
    29         int y=to[e];
    30         if(y==fa[x]){
    31             continue;
    32         }
    33         fa[y]=x;
    34         dep[y]=dep[x]+1;
    35         dfs(y);
    36     }
    37 }
    38 int main()
    39 {
    40 //    freopen("sdtg2.in","r",stdin);
    41 //    freopen("my.out","w",stdout);
    42     int T;
    43     scanf("%d%d",&n,&T);
    44     for(int i=1;i<=n;i++){
    45         scanf("%d",&v[i]);
    46     }
    47     for(int i=1;i<n;i++){
    48         int x,y;
    49         scanf("%d%d",&x,&y);
    50         Add(x,y);
    51     }
    52     dfs(1);
    53     for(int i=1;i<=T;i++){
    54         int k,x,y;
    55         scanf("%d%d%d",&k,&x,&y);
    56         if(!k){
    57             top=0;
    58             while(top<=50){
    59                 if(dep[x]<dep[y]){
    60                     swap(x,y);
    61                 }
    62                 q[++top]=v[x];
    63                 if(x==y){
    64                     break;
    65                 }
    66                 x=fa[x];
    67             }
    68             if(top>50){
    69                 printf("Y
    ");
    70             }
    71             else{
    72                 int ok=0;
    73                 sort(q+1,q+top+1);
    74                 for(int i=1;i<=top-2;i++){
    75                     if((ll)q[i]+q[i+1]>q[i+2]){
    76                         ok=1;
    77                         printf("Y
    ");
    78                         break;
    79                     }
    80                 }
    81                 if(!ok){
    82                     printf("N
    ");    
    83                 }
    84             }
    85         }
    86         else{
    87             v[x]=y;
    88         }
    89     }
    90     return 0;
    91 }
    Code3

    附加题:

    这是一道平面扫描的题目

    先正难则反,找非黄金三角形

    按角度排序之后,对于每个点i,与原点做一条直线,然后同在直线一侧的肯定是非黄金三角形,这样用组合数就可以计算了

    我们只需要考虑左侧,因为后面的点考虑左侧时会正好可以补上,做到不重不漏

    顺便说一下,向量a,b的叉积大于等于0(即a.x*b.y-a.y*b.x>=0)表示b在a的左边

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 #define MAXN 100005
     7 #define ll long long
     8 using namespace std;
     9 struct Point{
    10     ll x,y;
    11     double angle;
    12     Point(){
    13         x=y=0;
    14         angle=0;
    15     }
    16     friend bool operator < (const Point &p1,const Point &p2){
    17         return (p1.angle<p2.angle);
    18     }
    19     friend bool operator > (const Point &p1,const Point &p2){
    20         return !(p1<p2);
    21     }
    22     friend ll operator * (const Point &p1,const Point &p2){
    23         return (p1.x*p2.y-p2.x*p1.y);
    24     }
    25 }s[MAXN];
    26 int n;
    27 int main()
    28 {
    29 //    freopen("data.in","r",stdin);
    30     scanf("%d",&n);
    31     for(int i=1;i<=n;i++){
    32         scanf("%lld%lld",&s[i].x,&s[i].y);
    33         //atan222!!!
    34         s[i].angle=atan2((double)s[i].y,(double)s[i].x);
    35     }
    36     sort(s+1,s+n+1);
    37     int r=1,t=0;
    38     ll ans=0;
    39     for(int i=1;i<=n;i++){
    40         while(r%n+1!=i&&s[i]*s[r%n+1]>=0){
    41             r++; t++;
    42         }
    43         ans+=(ll)t*(t-1)/2;
    44         t--;
    45     }
    46     printf("%lld
    ",(ll)n*(n-1)*(n-2)/6-ans);
    47     return 0;
    48 }
    Code4

    总结:还模版题,模版个鬼啊,这么难


  • 相关阅读:
    Swift3 重写一个带占位符的textView
    Swift3 使用系统UIAlertView方法做吐司效果
    Swift3 页面顶部实现拉伸效果代码
    Swift3 倒计时按钮扩展
    iOS 获取当前对象所在的VC
    SpringBoot在IDEA下使用JPA
    hibernate 异常a different object with the same identifier value was already associated with the session
    SpringCloud IDEA 教学 番外篇 后台运行Eureka服务注册中心
    SpringCloud IDEA 教学 (五) 断路器控制台(HystrixDashboard)
    SpringCloud IDEA 教学 (四) 断路器(Hystrix)
  • 原文地址:https://www.cnblogs.com/w-h-h/p/7617582.html
Copyright © 2020-2023  润新知