zoukankan      html  css  js  c++  java
  • 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

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


  • 相关阅读:
    正则表达式
    面向对象(访问控制、继承、重写)
    你凌晨1点半会想什么
    10、android学习资源整理
    9、android开发之java.lang.verifyError(转载)
    8、android代码优化技术记录
    6、android 普通日志输出到SD卡
    刷机总结(阿里云os-->android4.2.2)注明:本文不是教程
    忘记树莓派密码怎么办?
    7、android的button如何平铺一张图片?
  • 原文地址:https://www.cnblogs.com/w-h-h/p/7617582.html
Copyright © 2011-2022 走看看