2014 牡丹江区域赛 B D I

http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=358

The 2014 ACM-ICPC Asia Mudanjiang Regional Contest

 

136 - The 2014 ACM-ICPC Asia Mudanjiang Regional Contest
Solved ID Title Ratio (AC/All)
Yes A Average Score 61.78% (456/738)
Yes B Building Fire Stations 10.40% (36/346)
  C Card Game 0.00% (0/0)
Yes D Domination 40.46% (123/304)
  E Excavator Contest 5.12% (2/39)
  F Fiber-optic Network 23.07% (3/13)
  G Garden and Sprinklers 0.00% (0/41)
  H Hierarchical Notation 9.37% (30/320)
Yes I Information Entropy 53.19% (366/688)
  J Jacobi Pattern 0.00% (0/2)
  K Known Notation 20.96% (96/458)

 

B Building Fire Stations

题意:给出一个树,找两个点建消防站,使离最近的消防站的距离最远的点的这个距离最小。点有20W个。

题解:这2个消防站肯定在树的直径上,二分这个距离d,分别把2个消防站放在与直径的2个端点距离d的位置。

20W个点,不碉的深搜会Segment Fault,我的深搜可是加了const &的碉深搜,才能过的。

 

听说的更碉的题解:在直径的中点把树切成两半,分别求直径中点,就得了。

代码:

  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<cmath>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 #include<queue>
 12 using namespace std;
 13 #define ll long long
 14 #define usll unsigned ll
 15 #define mz(array) memset(array, 0, sizeof(array))
 16 #define mf1(array) memset(array, -1, sizeof(array))
 17 #define minf(array) memset(array, 0x3f, sizeof(array))
 18 #define REP(i,n) for(i=0;i<(n);i++)
 19 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 20 #define RD(x) scanf("%d",&x)
 21 #define RD2(x,y) scanf("%d%d",&x,&y)
 22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 23 #define WN(x) printf("%d\n",x);
 24 #define RE  freopen("D.in","r",stdin)
 25 #define WE  freopen("huzhi.txt","w",stdout)
 26 #define mp make_pair
 27 #define pb push_back
 28 #define pf push_front
 29 #define ppf pop_front
 30 #define ppb pop_back
 31 const double pi=acos(-1.0);
 32 const double eps=1e-10;
 33 
 34 const int maxn=222222;
 35 const int maxm=2*maxn;
 36 
 37 int n;
 38 
 39 struct Edge {
 40     int v,next;
 41 } e[maxm];
 42 int en,head[maxn];
 43 
 44 inline void add(const int &x,const int &y) {
 45     e[en].v=y;
 46     e[en].next=head[x];
 47     head[x]=en++;
 48 }
 49 
 50 int ans[3];
 51 
 52 int anode,bnode;
 53 int len;
 54 inline void dfs1(const int &x,const int &f,const int &step) {
 55     if(step>len) {
 56         len=step;
 57         anode=x;
 58     }
 59     for(int i=head[x]; i!=-1; i=e[i].next) {
 60         if(e[i].v != f) dfs1(e[i].v , x , step+1);
 61     }
 62 }
 63 
 64 bool flag;
 65 int b[maxn],bn;
 66 inline void dfs2(const int &x,const int &f) {
 67     if(x==bnode) {
 68         flag=1;
 69         b[bn++]=x;
 70         return;
 71     }
 72     for(int i=head[x]; i!=-1; i=e[i].next) {
 73         if(e[i].v != f) {
 74             dfs2(e[i].v , x);
 75             if(flag) {
 76                 b[bn++]=x;
 77                 return;
 78             }
 79         }
 80     }
 81 }
 82 
 83 int _dis;
 84 int u[maxn];
 85 
 86 inline void dfs3(const int &x,const int &f,const int &step){
 87     if(step>_dis) {
 88         return;
 89     }
 90     u[x]=1;
 91     for(int i=head[x]; i!=-1; i=e[i].next) {
 92         if(e[i].v != f) dfs3(e[i].v , x , step+1);
 93     }
 94 }
 95 
 96 inline bool ok(const int &dis){
 97     int i;
 98     int nodec=b[dis];
 99     int noded=b[bn-1-dis];
100     len=0;
101     _dis=dis;
102     memset(u,0,sizeof(u));
103     dfs3(nodec,-1,0);
104     dfs3(noded,-1,0);
105     FOR(i,1,n)if(!u[i])return 0;
106     return 1;
107 }
108 inline void farm() {
109     int i;
110     len=0;
111     dfs1(1,-1,0);
112     //printf("%d!\n",anode);
113     bnode=anode;
114     len=0;
115     dfs1(bnode,-1,0);
116     //printf("%d!\n",anode);
117     flag=0,bn=0;
118     dfs2(anode,-1);
119 //    FOR(i,0,bn-1)printf("%d ,",b[i]);
120 //    printf("(a=%d , b=%d)\n",anode,bnode);
121 
122     int an;
123     int l=0,r=bn-1,mid;
124     while(l<=r){
125         mid=(l+r)>>1;
126 //        printf("%d,%d,%d\n",l,mid,r);
127         if(ok(mid))r=mid-1,an=mid;
128         else l=mid+1;
129     }
130     ans[0]=an;
131     ans[1]=b[an];
132     ans[2]=b[bn-1-an];
133     if(ans[1]==ans[2])ans[2]=(ans[1])%n+1;
134     return;
135 }
136 
137 int main() {
138     //re;
139     int T;
140     int i,j,x,y;
141     scanf("%d",&T);
142     while(T--) {
143         scanf("%d",&n);
144         memset(head,-1,sizeof(head));
145         en=0;
146         REP(i,n-1) {
147             scanf("%d%d",&x,&y);
148             add(x,y);
149             add(y,x);
150         }
151         farm();
152         printf("%d %d %d\n",ans[0],ans[1],ans[2]);
153     }
154     return 0;
155 }
View Code

 

D Domination

题意:在棋盘上没有棋的地方随机放棋,直到每一列每一行都有棋,求步数的期望。

题解:DP。dp[i][j][k]表示已经有i行有棋、j列有棋、已经放了k个棋 这种情况的概率。

我们是6000ms险过,也许DP的方式不对?

代码:

 1 #include <map>
 2 #include <set>
 3 #include <cmath>
 4 #include <queue>
 5 #include <stack>
 6 #include <cstdio>
 7 #include <string>
 8 #include <vector>
 9 #include <cstring>
10 #include <iostream>
11 #include <algorithm>
12 using namespace std;
13 
14 #define REP(i,n) for(i=0;i<n;i++)
15 #define FOR(i,x,y) for(i=x;i<=y;i++)
16 #define mz(x) memset(x,0,sizeof(x))
17 #define re freopen("in.txt","r",stdin)
18 #define pb push_back
19 #define ll long long
20 #define maxn 50005
21 #define mod 1000000009
22 
23 double dp[55][55][2555];
24 int n,m;
25 
26 double dfs(int x,int y,int z) {
27     if(x==0 || y==0 || z==0)return dp[x][y][z]=0.0;
28     if(dp[x][y][z]>=-0.5)return dp[x][y][z];
29     dp[x][y][z]=dfs(x-1,y,z-1)*(n-x+1)*y + dfs(x,y-1,z-1)*(m-y+1)*x + dfs(x-1,y-1,z-1)*(m-y+1)*(n-x+1);
30     if(x!=n || y!=m) dp[x][y][z]+= dfs(x,y,z-1)*(x*y-z+1);
31     dp[x][y][z]/=(double)(n*m-z+1);
32     //printf("(%d,%d,%d) %lf\n",x,y,z,dp[x][y][z]);
33     return dp[x][y][z];
34 }
35 
36 double farm(int _n,int _m) {
37     int i,j,k;
38     n=_n,m=_m;
39     FOR(i,0,n)FOR(j,0,m)FOR(k,0,n*m)dp[i][j][k]=-1.0;
40     dp[1][1][1]=1.0;
41     FOR(i,2,n)dp[i][1][i]=dp[i-1][1][i-1]*(n-i+1)/(n*m-i+1);
42     FOR(i,2,m)dp[1][i][i]=dp[1][i-1][i-1]*(m-i+1)/(n*m-i+1);
43     double ans=0.0;
44     FOR(i,1,n*m) {
45         ans+=dfs(n,m,i)*i;
46         //printf("%d %lf\n",i,dfs(n,m,i));
47     }
48     //printf("%.12lf\n",E);
49     return ans;
50 }
51 
52 int main() {
53     //re;
54     int T;
55     int n,m;
56     scanf("%d",&T);
57     while(T--) {
58         scanf("%d%d",&n,&m);
59         printf("%.12lf\n",farm(n,m));
60     }
61     return 0;
62 }
View Code

 

I Information Entropy

直接算,那啥是0的时候那个极限求完就是0。

代码:

 1 #include <map>
 2 #include <set>
 3 #include <cmath>
 4 #include <queue>
 5 #include <stack>
 6 #include <cstdio>
 7 #include <string>
 8 #include <vector>
 9 #include <cstring>
10 #include <iostream>
11 #include <algorithm>
12 using namespace std;
13 
14 
15 #define re freopen("in.txt","r",stdin)
16 #define pb push_back
17 #define ll long long
18 #define maxn 50005
19 #define mod 1000000009
20 const double e=2.7182818284590452353602874;
21 int n;
22 int p[111];
23 char s[10];
24 
25 double farm() {
26     double hx=0.0;
27     sort(p,p+n);
28     if(s[0]=='n') {
29         for(int i=0; i<n; i++) {
30             if(p[i]!=0) hx-=(1.0*p[i]) * (log(1.0*p[i]));
31         }
32         hx-=log(0.01)*100.0;
33         return hx;
34     } else if( s[0]=='d') {
35         for(int i=0; i<n; i++) {
36             if(p[i]!=0) hx-=(1.0*p[i]) * (log10(1.0*p[i]));
37         }
38         hx+=200.0;
39         return hx;
40     } else if(s[0]=='b') {
41         for(int i=0; i<n; i++) {
42             if(p[i]!=0) hx-=(1.0*p[i]) * (log2(1.0*p[i]));
43         }
44         hx-=log2(0.01)*100.0;
45         return hx;
46     }
47 }
48 
49 int main() {
50 //re;
51     int T;
52     scanf("%d",&T);
53     while(T--) {
54         scanf("%d%s",&n,s);
55         for(int i=0; i<n; i++) {
56             scanf("%d",&p[i]);
57         }
58         printf("%.12lf\n",farm()/100.0);
59     }
60     return 0;
61 }
View Code

 

posted @ 2014-10-13 00:36  带鱼Yuiffy  阅读(396)  评论(0编辑  收藏  举报