【2013长沙区域赛】部分题解 hdu4791—4801

1001:

签到题,二分一下即可

代码:

 1 #include <set>
 2 #include <map>
 3 #include <cmath>
 4 #include <ctime>
 5 #include <queue>
 6 #include <stack>
 7 #include <cstdio>
 8 #include <string>
 9 #include <vector>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 typedef unsigned long long ull;
16 typedef long long ll;
17 const int inf = 0x3f3f3f3f;
18 const double eps = 1e-8;
19 const int maxn = 1e5+10;
20 ll s[maxn],p[maxn],q[maxn];
21 ll res[maxn],minv[maxn];
22 int main(void)
23 {
24     #ifndef ONLINE_JUDGE
25         freopen("in.txt","r",stdin);
26     #endif
27     int t;
28     scanf ("%d",&t);
29     while (t--)
30     {
31         int n,m;
32         scanf ("%d%d",&n,&m);
33         minv[0] = inf;
34         for (int i = 0; i <  n; i++)
35         {
36             scanf ("%I64d%I64d",s+i,p+i);
37             res[i] = (s[i]-0) * p[i];
38         }
39         minv[n] = (ll)1<<50;
40         for (int i = n - 1; i >= 0; i--)
41         {
42             minv[i] = min(res[i],minv[i+1]);
43         }
44         for (int i = 0; i < m; i++)
45             scanf ("%I64d",q+i);
46         for (int i = 0; i < m; i++)
47         {
48             int idx = lower_bound(s,s+n,q[i]) - s;
49             ll ans = q[i] * p[idx-1];
50             printf("%I64d\n",min(ans,minv[idx]));
51         }
52     }
53     return 0;
54 }
View Code

 

1003:

题意:
几何题,有两个同心圆,撞到小圆会反弹,求在大圆中呆的时间

解法:

先判断能否进去,再判断能否碰撞

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <cmath>
 4 using namespace std;
 5 
 6 const double eps=1e-14;
 7 int dcmp(double x)
 8 {
 9     if(fabs(x)<eps)
10         return 0;
11     else
12         return x<0?-1:1;
13 }
14 
15 
16 double dot(double x1,double y1,double x2,double y2)
17 {
18     return x1*x2+y1*y2;
19 }
20 
21 int main()
22 {
23     //freopen("in.txt","r",stdin);
24     double rmax, rmin, r, x, y;
25     double vx, vy;
26     while(~scanf("%lf%lf%lf%lf%lf%lf%lf",&rmin, &rmax, &r, &x, &y, &vx, &vy))
27     {
28         if(dcmp(vx)==0)
29             vx=eps;
30         double k=vy/vx;
31         double d=fabs(y-k*x)/sqrt(k*k+1);
32 
33 
34         // 不能相交
35         if(d>=r+rmax || dot(x,y,vx,vy)>0)
36         {
37             printf("0\n");
38             continue;
39         }
40 
41         if(d>r+rmin)
42         {
43             double l1=sqrt((rmax+r)*(rmax+r)-d*d);
44             double t=l1/sqrt(vx*vx+vy*vy)*2.;
45             printf("%.6f\n",t);
46             continue;
47         }
48         double l1=sqrt((rmax+r)*(rmax+r)-d*d);
49         double l2=sqrt((rmin+r)*(rmin+r)-d*d);
50         double t=(l1-l2)/sqrt(vx*vx+vy*vy)*2.;
51         printf("%.6f\n",t);
52     }
53 
54     return 0;
55 }
View Code

1007:

题意:

有一个图,已知每个点的度数,问能否还原这个简单图,如果有多种方案要全部输出

简单图的定义是没有重边和自环

解法:

havel定理http://www.cnblogs.com/oneshot/p/4117632.html

 

1009:

题意:

有一棵树,每个点有一个权值(票数),还有一个种类,代表给like或者candle投票,每次可以花费x代价翻转某个子树,对于某些点他们已经被别人翻转,再次翻转的代价是y

消耗代价就是消耗like的票数(可以无限消耗,即使为负),求最后like和candle投票的差值得最大值

解法:

树形dp

每个点维护两个值,一个代表差值最大为多少,另一个代表差值最小为多少,进行转移即可

代码:

还没写

1010:

题意:

有c(m,3)支队伍,起初可以选一支,每次打败某只队伍后可以换成被打败的队伍,打败是有概率的,最后求最大概率

解法:

数据范围不大,直接dp就可以了

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 #include<string>
 6 #include<ctype.h>
 7 #include<math.h>
 8 using namespace std;
 9 #define eps 0.00000000001
10 int M,m,n;
11 double g[1010][1010];
12 int a[10010];
13 double dp[2][10010];
14 void ini()
15 {
16     M=m*(m-1)*(m-2)/6;
17     for(int i=0;i<M;i++)
18     {
19         for(int j=0;j<M;j++)
20             scanf("%lf",g[i]+j);
21     }
22     scanf("%d",&n);
23     for(int i=1;i<=n;i++)
24     {
25         scanf("%d",a+i);
26     }
27 }
28 void solve()
29 {
30     memset(dp,0,sizeof(dp));
31     for(int i=0;i<M;i++)
32     {
33         dp[0][i]=1.0;
34     }
35     for(int i=1;i<=n;i++)
36     {
37         for(int j=0;j<M;j++)
38         {
39             if(fabs(dp[(i-1)%2][j])<eps)
40             {
41                 continue;
42             }
43             dp[i%2][j]=max(dp[i%2][j],dp[(i-1)%2][j]*g[j][a[i]]);
44             dp[i%2][a[i]]=max(dp[i%2][a[i]],dp[(i-1)%2][j]*g[j][a[i]]);
45             dp[(i-1)%2][j]=0;
46         }
47     }
48     double ans=0;
49     for(int i=0;i<M;i++)
50     {
51         ans=max(ans,dp[n%2][i]);
52     }
53     printf("%.6f\n",ans);
54 }
55 int main()
56 {
57     while(scanf("%d",&m)!=EOF)
58     {
59         ini();
60         solve();
61     }
62     return 0;
63 }
View Code

 

1011:

题意:

给一个二维魔方的初始状态,求还原此魔方的最小步数,且步数不超过n步

解法:

由于限定了上界,所以直接dfs

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <memory.h>
 4 using namespace std;
 5 
 6 int n;
 7 int state[24];
 8 const int same[][4]={
 9     {0,1,2,3},
10     {4,5,10,11},
11     {6,7,12,13},
12     {8,9,14,15},
13     {16,17,18,19},
14     {20,21,22,23}
15 };
16 
17 const int change[][24]=
18 {
19     {1,3,0,2,23,22,4,5,6,7,10,11,12,13,14,15,16,17,18,19,20,21,9,8},
20     {2,0,3,1,6,7,8,9,23,22,10,11,12,13,14,15,16,17,18,19,20,21,5,4},
21     {20,1,22,3,10,4,0,7,8,9,11,5,2,13,14,15,6,17,12,19,16,21,18,23},
22     {6,1,12,3,5,11,16,7,8,9,4,10,18,13,14,15,20,17,22,19,0,21,2,23},
23     {0,1,11,5,4,16,12,6,2,9,10,17,13,7,3,15,14,8,18,19,20,21,22,23},
24     {0,1,8,14,4,3,7,13,17,9,10,2,6,12,16,15,5,11,18,19,20,21,22,23}
25 };
26 int tmp[24];
27 void Change(int type)
28 {
29     for(int i=0;i<24;i++)
30         tmp[i]=state[change[type][i]];
31 
32     memcpy(state,tmp,sizeof tmp);
33 }
34 
35 
36 // 得到相同的面数
37 int getSame()
38 {
39     int ans=6;
40     for(int i=0;i<6;i++)
41         for(int j=0;j<4;j++)
42             if(state[same[i][0]]!=state[same[i][j]])
43             {
44                 ans--;
45                 break;
46             }
47     return ans;
48 }
49 
50 int ans=0;
51 void dfs(int cur=0)
52 {
53     ans=max(ans,getSame());
54     if(cur>=n)
55         return ;
56     for(int i=0;i<6;i++)
57     {
58         Change(i);
59         dfs(cur+1);
60         Change(i^1);
61     }
62 }
63 
64 
65 
66 int main()
67 {
68     //freopen("in.txt","r",stdin);
69 
70     while(~scanf("%d",&n))
71     {
72         for(int i=0;i<24;i++)
73             scanf("%d",&state[i]);
74         ans=getSame();
75         dfs();
76         printf("%d\n",ans);
77     }
78 
79 
80     return 0;
81 }
View Code

 

posted @ 2015-09-02 13:01  PlasticSpirit  阅读(317)  评论(0编辑  收藏  举报