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 }
【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 }
【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 }
【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 }
【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 }
【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 }