2010 Asia Regional Tianjin Site —— Online Contest

2010 Asia Regional Tianjin Site —— Online Contest

 

【B】hdu 3622 Bomb Game

二分答案+2-SAT建图判定。1A。手残把距离函数写错,

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 #include<algorithm>
  5 using namespace std;
  6 const int maxn = 211;
  7 #define eps 1e-5
  8 struct Point{
  9     double  x, y;
 10 }seq[maxn][2];
 11 int n;
 12 int mp[maxn*2][maxn*2];
 13 
 14 int col[maxn];
 15 bool instack[maxn];
 16 int dep;
 17 int scnt ;
 18 int nn;
 19 int st[maxn],top;
 20 int dfn[maxn],low[maxn];
 21 void tarjan(int u  )
 22 {
 23     low[u] = dfn[u] = dep ++ ;
 24     instack[u] = true;
 25     st[++top] = u;
 26     for(int i = 1 ; i <= nn ; i ++ )
 27     if(mp[u][i])
 28     {
 29         if(dfn[i] == -1 )
 30         {
 31             tarjan(i);
 32             low[u] = min(low[u] , low[i]);
 33         }
 34         else if(instack[i])
 35         {
 36             low[u] = min(low[u] , dfn[i]);
 37         }
 38     }
 39     if(low[u] == dfn[u])
 40     {
 41         int x;
 42         do
 43         {
 44             x = st[top--];
 45             instack[x] = false;
 46             col[x] = scnt;
 47         }
 48         while( x != u ) ;
 49         scnt ++ ;
 50     }
 51 }
 52 void base()
 53 {
 54     memset(dfn,-1,sizeof(dfn));
 55     memset(instack,0,sizeof(instack));
 56     dep = 0 ;
 57     top = 0 ;
 58     scnt = 1 ;
 59     for(int i = 1 ; i <= nn ; i ++ )
 60     {
 61         if(dfn[i] == -1 )
 62         {
 63             tarjan(i);
 64         }
 65     }
 66 }
 67 void add(int u, int v){
 68     mp[u][v] = 1;
 69     return ;
 70 }
 71 double diss(Point p, Point q){
 72     return (p.x  - q.x)*(p.x  - q.x) + (p.y  - q.y)*(p.y  - q.y);
 73 }
 74 bool calc(double limit){
 75     limit = 4*limit * limit;
 76     memset(mp,0,sizeof(mp));
 77     for (int i=1;i<=n;i++)
 78         for (int j = i + 1;j<=n;j++){
 79             if (i != j){
 80                 if (diss(seq[i][0], seq[j][0])<limit){
 81                     add(i,j + n);
 82                     add(j,i + n);
 83                 }
 84                 if (diss(seq[i][0], seq[j][1])<limit){
 85                     add(i,j);
 86                     add(j + n,i + n);
 87                 }
 88                 if (diss(seq[i][1], seq[j][0])<limit){
 89                     add(i + n,j + n);
 90                     add(j ,i );
 91                 }
 92                 if (diss(seq[i][1], seq[j][1])<limit){
 93                     add(i + n,j);
 94                     add(j +n,i);
 95                 }
 96             }
 97         }
 98         nn = 2 * n;
 99         base();
100         for(int i = 1 ; i <= n ; i ++ )
101         {
102             if(col[i] == col[i+n]) return false;
103         }
104         return true;
105 }
106 int main()
107 {
108     while (scanf("%d", &n)==1){
109         for (int i=1;i<=n;i++){
110             scanf("%lf%lf%lf%lf", &seq[i][0].x, &seq[i][0].y, &seq[i][1].x, &seq[i][1].y);
111         }
112 
113         double l = 0.0, r = 1000000.0;
114         while (r > l + eps ){
115             //puts("sdfklslkdf");
116             double mid = (l + r)/2.0;
117 
118             if (calc(mid)){
119                 l = mid + eps;
120             }else{
121                 r = mid;
122             }
123         }
124         printf("%.2lf\n", l);
125     }
126     return 0;
127 }
hdu3622

【D】hdu3625 Examining the Rooms

环排列的方案数。斯特林第一类数的应用。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define LL long long
 4 
 5 LL s[25][25];
 6 
 7 LL f[25];
 8 
 9 int main()
10 {
11     f[1] = 1;
12     s[1][1] = 1;
13     s[1][0] = 0;
14     for (int i=2;i<=20;i++){
15         for (int j = 1;j<=i;j++){
16             s[i][j] = s[i-1][j-1] + (i - 1) * s[i-1][j];
17         }
18         f[i] = f[i-1] * i;
19     }
20     int cas;
21     scanf("%d", &cas);
22     while (cas--){
23         int n,m ;
24         scanf("%d%d", &n, &m);
25         LL sum = 0;
26         for (int i=1;i<=m;i++){
27             sum += (s[n][i] - s[n-1][i-1]);
28         }
29         printf("%.4lf\n" , (sum*1.0)/f[n]);
30     }
31     return 0;
32 }
hdu3625

【E】hdu3626 For

水题,暴力枚举。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<math.h>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 1111;
 8 struct Point{
 9     int x, y;
10     bool operator < (Point & cur) const{
11         if (x<cur.x && y<cur.y)
12             return true;
13         return false;
14     }
15 }seq[maxn];
16 int n;
17 int main()
18 {
19     int cast = 0;
20     while (scanf("%d", &n)==1)
21     {
22         if (n == 0)
23             break;
24         for (int i=1;i<=n;i++){
25             scanf("%d%d", &seq[i].x, &seq[i].y);
26         }
27         if (cast > 0)
28             puts("");
29         printf("Case %d:\n", ++ cast);
30         for (int i=1;i<=n;i++){
31             int ans = 0;
32             for (int j=1;j<=n;j++)
33                 if (i != j){
34                     if (seq[i] < seq[j]){
35                         if (ans == 0){
36                             ans  = j;
37                         }else{
38                             if ((seq[j].x < seq[ans].x) || (seq[j].x == seq[ans].x && seq[j].y < seq[ans].y))
39                             {
40                                 ans = j;
41                             }
42                         }
43                     }
44                 }
45             if (ans == 0){
46                 puts("-1 -1");
47             }else{
48                 printf("%d %d\n",seq[ans].x, seq[ans].y);
49             }
50         }
51 
52     }
53     return 0;
54 }
hdu3626

【G】hdu3628 HeavenHelix

二分答案 + 积分。。sim积分乱搞。。吐血的精度。Orz,灿哥推出来公式,没积出来,直接搞。

 

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<math.h>
 4 #include<vector>
 5 #define eps 0.00000001
 6 using namespace std;
 7 
 8 double r,w,v,x,e;
 9 double V;
10 
11 double f(double a,double b)
12 {
13     return  sqrt(r*r + v*v * (b-a) * (b-a));
14 }
15 
16 double sim(double a,double b,int n)
17 {
18     double h = (b-a) / n;
19     double ans = f(a,b) + f(b,b);
20     for(int i=1;i<n;i+=2) ans += 4 * f(a+i*h,b);
21     for(int i=2;i<n;i+=2) ans += 2 * f(a+i*h,b);
22 
23     return ans * h / 3;
24 }
25 
26 double rom(double a,double b,double es)
27 {
28     vector<double> t;
29     double  h = b-a,last,curr;
30     int k = 1, i  = 1;
31     t.push_back(h * (f(a,b) + f(b,b)) / 2);
32     do {
33         last = t.back();
34         curr = 0;
35         double x = a + h/2.0;
36         for (int j = 0;j<k;j++){
37             curr += f(x,b);
38             x += h;
39         }
40         curr = (t[0] + h*curr)/2;
41         double k1 = 4.0/3.0, k2 = 1.0/3.0;
42         for (int j = 0;j<i;j++){
43             double temp = k1 * curr - k2*t[j];
44             t[j] = curr;
45             curr = temp;
46             k2/=4*k1 - k2;
47             k1 = k2 + 1;
48         }
49         t.push_back(curr);
50         k *=2;
51         h /= 2;
52         i++;
53     }while (fabs(last - curr) < es);
54     return t.back();
55 }
56 
57 int main()
58 {
59     while(scanf("%lf%lf",&r,&w))
60     {
61         scanf("%lf%lf%lf",&v,&x,&e);
62         if(fabs(v) < eps && fabs(x) < eps) break;
63 
64         V = sqrt(r*w*r*w + v*v);
65         double ans = e/x/V;
66 
67         double p = 30 * 60 * 24 * 60;
68         double q = 0;
69         double mid;
70         double res;
71 
72         while(fabs(p - q) > eps){
73 
74             mid = (p+q)/2.0;
75             res = sim(0,mid,30000);
76             if(res > ans) p = mid;
77             else q = mid;
78         }
79 
80         printf("%.4lf\n",mid);
81     }
82     return 0;
83 }
hdu 3628

【H】hdu3629 Convex

给定平面上N个点,求能组成凸四边形的总方案数。求出凹四边形的方案数,作减法。。

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 typedef  long long LL;
 8 const double PI = acos(-1.0);
 9 const int maxn = 777;
10 
11 int x[maxn], y[maxn];
12 
13 double ang[maxn];
14 int n;
15 
16 double dissang(double a, double b)
17 {
18     if (a > b)
19         return b + 2*PI - a;
20     return b - a;
21 }
22 LL solve()
23 {
24     LL res = ((LL)n*(n-1)*(n-2)*(n-3))/(2*3*4);
25     for (int k = 1; k<=n; k++)
26     {
27         int idx = 0;
28         for (int i=1; i<=n; i++)
29             if (i!=k)
30             {
31                 ang[idx++] = atan2((double)(y[i] - y[k]), (double)(x[i] - x[k]));
32             }
33         sort(ang,ang+idx);
34         LL tmp = ((LL)idx*(idx-1)*(idx-2))/(3*2*1);//C(n-1, 3),三角形的总个数
35         for (int i = 0, j = 0; i<idx; i++)
36         {
37             while (j < idx + i)
38             {
39                 if (dissang(ang[i],ang[j % idx]) > PI)
40                     break;
41                 j++;
42             }
43             LL temp = (LL)(j- i - 1) * (j - i - 2)/2;//C(j - i -1,2)
44             tmp -= temp;
45         }
46         res -= tmp;
47     }
48     return res;
49 }
50 int main()
51 {
52     int cas;
53     scanf("%d", &cas);
54     while (cas--)
55     {
56         scanf("%d", &n);
57         for (int i=1; i<=n; i++)
58         {
59             scanf("%d%d", &x[i], &y[i]);
60         }
61 
62         printf("%I64d\n", solve());
63 
64     }
65     return 0;
66 }
hdu3629

 

【J】hdu3631 Shortest Path

最短路。。。。。最后20s提交过了,脑残下标。。。

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 #include<algorithm>
  5 using namespace std;
  6 
  7 #define LL long long
  8 const int maxn = 333;
  9 LL mp[maxn][maxn];
 10 LL f[maxn][maxn];
 11 bool mark[maxn];
 12 
 13 int n,m, Q;
 14 int que[maxn*maxn];
 15 int vis[maxn];
 16 void spfa(int x)
 17 {
 18     int head = 0, tail = 0;
 19     memset(vis,0,sizeof(vis));
 20     que[++tail] = x;
 21     vis[x] = 1;
 22     for (int i=1;i<=n;i++)
 23         if (i!=x && mark[i] && mp[x][i]>=0){
 24             que[++tail] = i;
 25             f[x][i] = mp[x][i];
 26             vis[i] = 1;
 27         }
 28     while (head < tail)
 29     {
 30         int u = que[++head];
 31         for (int i=1;i<=n;i++)
 32         {
 33             if (i != u && mark[i] && f[u][i] >= 0){
 34                 LL tmp = f[x][u] + f[u][i];
 35                 if (f[x][i] == -1 || tmp < f[x][i]){
 36                     f[x][i] = tmp;
 37                     if (!vis[i]){
 38                         que[++tail] = i;
 39                         vis[i] = 1;
 40                     }
 41                 }
 42             }
 43         }
 44         vis[u] = 0;
 45     }
 46 
 47 
 48 
 49 //dfsaaa
 50     head = 0, tail = 0;
 51     memset(vis,0,sizeof(vis));
 52     que[++tail] = x;
 53     vis[x] = 1;
 54     for (int i=1;i<=n;i++)
 55         if (i!=x && mark[i] && mp[i][x]>=0){
 56             que[++tail] = i;
 57             f[i][x] = mp[i][x];
 58             vis[i] = 1;
 59         }
 60     while (head < tail)
 61     {
 62         int u = que[++head];
 63         for (int i=1;i<=n;i++)
 64         {
 65             if (i != u && mark[i] && f[i][u] >= 0){
 66                 LL tmp = f[u][x] + f[i][u];
 67                 if (f[i][x] == -1 || tmp < f[i][x]){
 68                     f[i][x] = tmp;
 69                     if (!vis[i]){
 70                         que[++tail] = i;
 71                         vis[i] = 1;
 72                     }
 73                 }
 74             }
 75         }
 76         vis[u] = 0;
 77     }
 78 //***********
 79     for (int i=1;i<=n;i++)
 80         for (int j=1;j<=n;j++)
 81             if (mark[i] && mark[j]){
 82                 if (f[i][x] >=0 && f[x][j]>=0){
 83                     LL tmp = f[i][x] + f[x][j];
 84                     if (tmp < f[i][j] || f[i][j] == -1){
 85                         f[i][j] = tmp;
 86                     }
 87                 }
 88             }
 89     return ;
 90 }
 91 int q;
 92 int main()
 93 {
 94     int cast = 0;
 95     while (scanf("%d%d%d", &n, &m , &q)==3)
 96     {
 97         if (n == 0 && m==0 && q==0)
 98             break;
 99         memset(mp,-1,sizeof(mp));
100         for (int i=1;i<=m;i++)
101         {
102             int u,v;
103             LL val;
104             scanf("%d%d%I64d", &u,&v,&val);
105             u++;
106             v++;
107             if (mp[u][v]  == -1){
108                 mp[u][v] = val;
109             }else if (val < mp[u][v]){
110                 mp[u][v] = val;
111             }
112         }
113         memset(f,-1,sizeof(f));
114         memset(mark,0,sizeof(mark));
115         for (int i=1;i<=n;i++)
116         {
117             f[i][i] = 0;
118         }
119         if (cast > 0)
120             puts("");
121         printf("Case %d:\n", ++cast);
122         while (q--){
123             int id;
124             int x,y;
125             scanf("%d", &id);
126             if (id == 0){
127                 scanf("%d", &x);
128                 x++;
129                 if (mark[x]){
130                     printf("ERROR! At point %d\n",x-1);
131                 }else{
132                     mark[x] = 1;
133                     spfa(x);
134                 }
135             }else{
136                 scanf("%d%d", &x, &y);
137                 x++;
138                 y++;
139                 if (!mark[x] || !mark[y]){
140                     printf("ERROR! At path %d to %d\n", x-1, y-1);
141                 }else{
142                     if (f[x][y] >=0){
143                         printf("%I64d\n",f[x][y]);
144                     }else{
145                         puts("No such path");
146                     }
147                 }
148             }
149         }
150     }
151     return 0;
152 }
hdu3631

 

转载于:https://www.cnblogs.com/wangsouc/articles/3356851.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值