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
|
题意:给出一个树,找两个点建消防站,使离最近的消防站的距离最远的点的这个距离最小。点有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 }
题意:在棋盘上没有棋的地方随机放棋,直到每一列每一行都有棋,求步数的期望。
题解: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 }
直接算,那啥是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 }