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
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
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
-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\n",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 }
T2:
用组合数学的知识,先把所有的情况算出来,然后减去共线的情况即可
注意斜的用gcd算,不能用组合数了