1. 程式人生 > >NOIP2014-10-30模擬賽

NOIP2014-10-30模擬賽

職責 std span con algo 思想 class 支持 可能

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\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 }
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\n",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\n");
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\n");
78                         break;
79                     }
80                 }
81                 if(!ok){
82                     printf("N\n");    
83                 }
84             }
85         }
86         else{
87             v[x]=y;
88         }
89     }
90     return 0;
91 }
Code3

附加題:

這是一道平面掃描的題目

先正難則反,找非黃金三角形

按角度排序之後,對於每個點i,與原點做一條直線,然後同在直線一側的肯定是非黃金三角形,這樣用組合數就可以計算了

我們只需要考慮左側,因為後面的點考慮左側時會正好可以補上,做到不重不漏

技術分享
 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\n",(ll)n*(n-1)*(n-2)/6-ans);
47     return 0;
48 }
Code4

總結:還模版題,模版個鬼啊,這麽難


NOIP2014-10-30模擬賽