2013 Multi-University Training Contest 1
来源:互联网 发布:bugzilla linux 下载 编辑:程序博客网 时间:2024/06/05 22:48
这场比赛。。。伤心了
A - Harvest Moon(HDU4600)
题意:给你好多种种子,每种都有价格和收益。再给你一片地,问你只选一种种子播种的最大收益。
思路:枚举每种种子然后模拟。我很煞笔的开了个数组记录大小为i的土地的数量。TLE到死,最后很猥琐的除GCD,950ms水过。
#include<stdio.h>#include<string.h>#include<stdlib.h>#define maxn 1100#define maxm 11#define Clear(a,b) memset(a,b,sizeof(a))#define LL __int64int gcd(int a,int b) { if (b == 0) return a; else return gcd(b,a%b);}inline LL Max(LL a,LL b){ if (a > b) return a; return b;}inline LL Min(LL a,LL b){ if (a > b) return b; return a;}short int rec[maxn][maxm] = {0};void cal_grid(int w,int h,int g[maxm]){ int w3,h3; g[9] = (w / 3) * (h / 3); w3 = w % 3; h3 = h % 3; g[3 * w3 + 3 * h3 - w3 * h3]++; g[w3 * 3] += ((h - 3) / 3); g[h3 * 3] += ((w - 3) / 3); g[w3 * h3] += 2; return ;}LL cal_get(int day,int mon,int q,int p,int n,int m,int g[maxm]){ int i,j,rest,num; LL money = mon; //day--; //printf("day:%d\n",day); //for(i = 1;i <= 9;i++) printf("%d ",g[i]);printf("\n"); //printf("%d %d %d %d",q,p,n,m); if (m == 0) { day /= n; n /= n; for(i = 0;i <= day;i++){ if (i >= 1) for(j = 1;j <= 9;j++) if (rec[i][j] > 0){ money += rec[i][j] * j * p; g[j] += rec[i][j]; rec[i][j] = 0; } for(j = 9;j >= 1;j--) if (g[j] >= 0 && i + n <= day && j * p > q){ num = Min(money / q,g[j]); money -= num * q; g[j] -= num; rec[i+1][j] += num; } } } else { //printf("\n%dxxx%d\n",i,day); int GCD = gcd(n,m); day /= GCD; n /= GCD; m /= GCD; for(i = 0;i <= day;i++){ rest = day - i; for(j = 9;j >= 1;j--) if (rec[i][j] > 0) { money += rec[i][j] * j * p; if (i + m <= day) rec[i+m][j] += rec[i][j]; rec[i][j] = 0; } //printf("%dxxx%d\n",i,day); for(j = 9;j >= 1;j--) if (g[j] > 0) { num = Min(money / q,g[j]); //sb了 if (rest >= n && (((rest - n) / m) * p + p) * j > q) { money -= num * q; rec[i+n][j] += num; g[j] -= num; } } } } //printf("OK\n"); return money;}int Work(){ int Y,i,j,h,w,A,D,q,p,n,m; LL ans = 0; int grid[maxm] = {0},grid2[maxm] = {0}; scanf("%d%d%d%d%d",&w,&h,&A,&D,&Y); cal_grid(h,w,grid); //for(i = 1;i <= 9;i++) printf("%d ",grid[i]);printf("\n"); for(i = 1;i <= A;i++) { scanf("%d%d%d%d",&q,&p,&n,&m); for(j = 0;j < 10;j++) grid2[j] = grid[j]; ans = Max(ans,cal_get(D,Y,q,p,n,m,grid2)); } printf("%I64d\n",ans); //大傻逼 return 0;}int main(){ int Cas; //freopen("test.in","r",stdin); //freopen("test.out","w",stdout); scanf("%d",&Cas); while(Cas--) Work(); return 0;}
C - Partition(HDU 4602)
这题猥琐的算前几项然后搜的公式
#include<stdio.h>#include<iostream>#include<stdlib.h>#include<string>#include<string.h>#define LL _int64const LL Mod = 1000000007;LL QPow(LL x,LL n){ if (n == 0) return 1; if (n == 1) return x; LL tmp = QPow(x,n>>1); if (n & 1) return (((tmp * tmp) % Mod) * x) % Mod; else return (tmp * tmp) % Mod;}LL Work(){ LL n,k,dif; scanf("%I64d%I64d",&n,&k); dif = n - k; if (dif < 0) printf("0\n"); else if (dif == 0) printf("1\n"); else if (dif == 1) printf("2\n"); else printf("%I64d\n",(dif+3) * QPow(2,dif-2) % Mod); return 0;}int main(){ int Cas; scanf("%d",&Cas); while(Cas--) Work(); return 0;}F - Magic Ball Game(HDU 4605)
题意:给你一颗树,想象一个小球从根往下落,问你小球从根到某点的概率。
思路:首先,将路径统计一下,分为左路径和右路径,然后分别统计有多少大于X的。统计我用的傻逼树。
//先分左右,离线保存,两颗傻逼树,DFS#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <set>#include <map>#include <vector>#include <queue>#include <ctime>#pragma comment(linker, "/STACK:32000000")using namespace std;#define LL long long#define Clear(a,b) memset(a,b,sizeof(a))const int N = 300010;const int INF=0x7FFFFFFF;vector<int> O[N];int X[N],ansx[N],ansy[N],son[N][2],w[N];struct SBT{ int key,left,right,size;} Tree_L[N],Tree_R[N];int Root_L,Root_R,top;void left_rot(int &x,SBT tree[]){ int y = tree[x].right; tree[x].right = tree[y].left; tree[y].left = x; tree[y].size = tree[x].size;//转上去的节点数量为先前此处节点的size tree[x].size = tree[tree[x].left].size + tree[tree[x].right].size + 1; x = y;}void right_rot(int &x,SBT tree[]){ int y = tree[x].left; tree[x].left = tree[y].right; tree[y].right = x; tree[y].size = tree[x].size; tree[x].size = tree[tree[x].left].size + tree[tree[x].right].size + 1; x = y;}void maintain(int &x,bool flag,SBT tree[]){ if(flag == false)//左边 { if(tree[tree[tree[x].left].left].size > tree[tree[x].right].size)//左孩子的左子树大于右孩子 right_rot(x,tree); else if(tree[tree[tree[x].left].right].size > tree[tree[x].right].size)//右孩子的右子树大于右孩子 { left_rot(tree[x].left,tree); right_rot(x,tree); } else return; } else //右边 { if(tree[tree[tree[x].right].right].size > tree[tree[x].left].size)//右孩子的右子树大于左孩子 left_rot(x,tree); else if(tree[tree[tree[x].right].left].size > tree[tree[x].left].size)//右孩子的左子树大于左孩子 { right_rot(tree[x].right,tree); left_rot(x,tree); } else return; } maintain(tree[x].left,false,tree); maintain(tree[x].right,true,tree); maintain(x,true,tree); maintain(x,false,tree);}/**insert没有合并相同的元素,如果出现相同的元素则把它放到右子树上,这样能保证求第k小数的时候对相同元素也能正确*/bool find(int &x,int key,SBT tree[]){ if (x == 0) return 0; if (key == tree[x].key) return 1; if (key < tree[x].key) return find(tree[x].left,key,tree); else return find(tree[x].right,key,tree);}void insert(int &x,int key,SBT tree[]){ if(x == 0) { x = ++top; tree[x].left = tree[x].right = 0; tree[x].size = 1; tree[x].key = key; } else { tree[x].size ++; if(key < tree[x].key) insert(tree[x].left,key,tree); else insert(tree[x].right,key,tree);//相同元素插入到右子树中 maintain(x, key >= tree[x].key,tree);//每次插入把平衡操作压入栈中 }}int del(int &p,int w,SBT tree[]){ if (tree[p].key==w || (tree[p].left==0 && w<tree[p].key) || (tree[p].right==0 && w>tree[p].key)) { int delnum=tree[p].key; if (tree[p].left==0 || tree[p].right==0) p=tree[p].left+tree[p].right; else tree[p].key=del(tree[p].left,INF,tree); return delnum; } if (w<tree[p].key) return del(tree[p].left,w,tree); else return del(tree[p].right,w,tree);}int remove(int &x,int key,SBT tree[]){ int d_key; //if(!x) return 0; tree[x].size --; if((key == tree[x].key)||(key < tree[x].key && tree[x].left == 0) || (key>tree[x].key && tree[x].right == 0)) { d_key = tree[x].key; if(tree[x].left && tree[x].right) { tree[x].key = remove(tree[x].left,tree[x].key+1,tree); } else { x = tree[x].left + tree[x].right; } } else if(key > tree[x].key) d_key = remove(tree[x].right,key,tree); else if(key < tree[x].key) d_key = remove(tree[x].left,key,tree); return d_key;}int getmin(int root,SBT tree[]){ int x; for(x = root ; tree[x].left; x = tree[x].left); return tree[x].key;}int getmax(int root,SBT tree[]){ int x; for(x = root ; tree[x].right; x = tree[x].right); return tree[x].key;}int select(int &x,int k,SBT tree[])//求第k小数{ int r = tree[tree[x].left].size + 1; if(r == k) return tree[x].key; else if(r < k) return select(tree[x].right,k - r,tree); else return select(tree[x].left,k,tree);}int rank(int &x,int key,SBT tree[])//求key排第几{ if(key < tree[x].key) return rank(tree[x].left,key,tree); else if(key > tree[x].key) return rank(tree[x].right,key,tree) + tree[tree[x].left].size + 1; return tree[tree[x].left].size + 1;}int pred(int &x,int y,int key,SBT tree[])//前驱 小于{ if(x == 0) return y; if(tree[x].key < key) return pred(tree[x].right,x,key,tree); else return pred(tree[x].left,y,key,tree);}int succ(int &x,int y,int key,SBT tree[])//后继 大于{ if(x == 0) return y; if(tree[x].key > key) return succ(tree[x].left,x,key,tree); else return succ(tree[x].right,y,key,tree);}void inorder(int &x,SBT tree[]){ if(x==0) return; else { inorder(tree[x].left,tree); cout<<x<<" "<<tree[x].key<<" "<<" "<<tree[x].size<<" "<<tree[tree[x].left].key<<" "<<tree[tree[x].right].key<<endl; inorder(tree[x].right,tree); }}//模板void dfs(int x,int Num_L,int Num_R){ //Cal int i,t1,t2; //printf("%d %d yy\n",x,O[x].size()); for(i = 0;i < O[x].size();i++){ int tmp = O[x][i]; //printf("fuck\n"); if (find(Root_L,X[tmp],Tree_L) || find(Root_R,X[tmp],Tree_R)) continue; //tot = Num_L + Num_R; //printf("fuck\n"); insert(Root_L,X[tmp],Tree_L); insert(Root_R,X[tmp],Tree_R); t1 = rank(Root_L,X[tmp],Tree_L); t2 = rank(Root_R,X[tmp],Tree_R); remove(Root_L,X[tmp],Tree_L); remove(Root_R,X[tmp],Tree_R); t1--;t2--; //printf("fuck %d %d %d %d\n",t1,t2,Num_L,Num_R); ansx[tmp] = t2; ansy[tmp] = t1 * 3 + (Num_L - t1) + t2 * 3 + (Num_R - t2); } //printf("L\n"); //L if (son[x][0] > 0) { insert(Root_L,w[x],Tree_L); dfs(son[x][0],Num_L+1,Num_R); remove(Root_L,w[x],Tree_L); } //printf("R\n"); //R if (son[x][1] > 0) { insert(Root_R,w[x],Tree_R); dfs(son[x][1],Num_L,Num_R+1); remove(Root_R,w[x],Tree_R); } return ;}void Work(){ Root_L = Root_R = top = 0; int n,m,i,u,a,b; Clear(son,0); Clear(ansx,-1); Clear(ansy,-1); Clear(w,0); Clear(X,0); scanf("%d",&n); for(i = 1;i <= n;i++) O[i].clear(); for(i = 1;i <= n;i++) scanf("%d",&w[i]); scanf("%d",&m); for(i = 1;i <= m;i++) scanf("%d%d%d",&u,&a,&b), son[u][0] = a, son[u][1] = b; scanf("%d",&m); for(i = 1;i <= m;i++) scanf("%d%d",&u,&X[i]), O[u].push_back(i); //printf("xxxx\n"); dfs(1,0,0); //printf("xxxx\n"); for(i = 1;i <= m;i++) if (ansx[i] == -1) printf("0\n"); else printf("%d %d\n",ansx[i],ansy[i]); return ;}int main(){ int cas; // freopen("test.in","r",stdin); // freopen("test.out","w",stdout); scanf("%d",&cas); while(cas--) Work(); return 0;}
G - Occupy Cities(HDU 4606)
floyd+二分+最小路径覆盖
#include<iostream>#include<string.h>#include<stdio.h>#include<string>#include<math.h>#define oo 1e9#define eps 1e-8#define maxn 500#define maxm 10000using namespace std;struct Point{ int u,v; Point(){} Point(double a,double b):u(a),v(b){} Point operator - (const Point p) {return Point(u-p.u,v-p.v);}}p[maxn],wall[maxn];double ma[maxn][maxn];int map[maxn][maxn],match[maxn],id[maxn];bool vis[maxn];int n,m,PP,T,N,M;int dlcmp(double x) {return x<-eps?-1:x>eps;}double sqr(double x) {return x*x;}double dist(Point a,Point b) {return sqrt(sqr(a.u-b.u)+sqr(a.v-b.v));}double cross(Point a,Point b) {return a.u*b.v-b.u*a.v;}int segment_intersect(Point s1,Point e1,Point s2,Point e2){ if (max(s1.u,e1.u)>min(s2.u,e2.u)&&max(s2.u,e2.u)>min(s1.u,e1.u)&&max(s1.v,e1.v)>min(s2.v,e2.v)&&max(s2.v,e2.v)>min(s1.v,e1.v)&& dlcmp(cross(e1-s1,s2-s1))*dlcmp(cross(e1-s1,e2-s1))<0&&dlcmp(cross(e2-s2,s1-s2))*dlcmp(cross(e2-s2,e1-s2))<0) return 1; else return 0;}bool NO( int x, int y ){ for ( int i = 1; i <= m; ++i ) { if ( segment_intersect(p[x],p[y],wall[i],wall[i+m]) ) return 0; } return 1;}double makemap(){ for ( int i = 1; i <= N; ++i ) for ( int j = 1; j <= N; ++j ) if ( i != j ) ma[i][j] = oo; else ma[i][j] = 0; for ( int i = 1; i <= N; ++i ) for ( int j = 1; j < i; ++j ) if ( NO(i,j) ) { ma[i][j] = min(ma[i][j],dist(p[i],p[j])); ma[j][i] = ma[i][j]; } for ( int k = 1; k <= N; ++k ) for ( int i = 1; i <= N; ++i ) if ( k != i ) for ( int j = 1; j <= N; ++j ) if ( i !=j && k != j && ma[i][j] > ma[i][k] + ma[k][j] && ma[i][k] < oo && ma[k][j] < oo ) ma[i][j] = ma[i][k]+ma[k][j]; double maxx = 0; for ( int i = 1; i <= n; ++i ) for ( int j = 1; j < i; ++j ) if ( maxx < ma[i][j] ) maxx = ma[i][j]; return maxx;}int find( int x ){ for ( int i = 1; i <= n; ++i ) if ( map[x][i] == 1 && vis[i] == 0 ) { vis[i] = 1; if ( match[i] == 0 || find(match[i]) ) { match[i] = x; return 1; } } return 0;}bool can( double mid ){ memset(map,0,sizeof(map)); for ( int i = 1; i <= n; ++i ) for ( int j = 1; j <= n; ++j ) if ( id[i] < id[j] &&ma[i][j]-mid <=0 ) map[i][j] = 1; memset(match,0,sizeof(match)); int res = 0; for ( int i = 1; i <= n; ++i ) { memset(vis,0,sizeof(vis)); res += find(i); } if ( n - res <= PP ) return 1; else return 0;}int main(){ int u; scanf("%d",&T); while ( T-- ) { scanf("%d%d%d",&n,&m,&PP); for ( int i = 1; i <= n; ++i ) scanf("%d%d",&p[i].u,&p[i].v); for ( int i = 1; i <= m; ++i ) { scanf("%d%d%d%d",&p[i+n].u,&p[i+n].v,&p[i+n+m].u,&p[i+n+m].v); wall[i].u = p[i+n].u; wall[i].v = p[i+n].v; wall[i+m].u = p[i+n+m].u; wall[i+m].v=p[i+n+m].v; } for ( int i = 1; i <= n; ++i ) { scanf("%d",&u); id[u] = i; } N = n + m + m; double r = makemap(),l = 0.0,mid; while ( (r-l) > eps ) { mid = ( r + l ) / 2; if ( can(mid) == 1 ) r = mid; else l = mid; } printf("%.2lf\n",r); } return 0;}
H - Park Visit(HDU 4607)
先用两遍DFS求出直径ans,当k小于等于直径时,答案为k-1;否则答案为(k-ans)*2+ans-1#include<iostream>#include<string.h>#include<string>#include<stdio.h>#define maxn 200000#define maxm 500000using namespace std;int first[maxn],cnt,dep[maxn];struct edd{ int v,next;}e[maxm];void add( int u, int v ){ e[cnt].v = v; e[cnt].next = first[u]; first[u] = cnt++;}void dfs(int u, int fa, int deep ){ dep[u] = deep; for ( int i = first[u]; i != -1; i = e[i].next ) { int v = e[i].v; if ( v != fa ) dfs(v,u,deep+1); }}int main(){ int T,n,m,u,v; scanf("%d",&T); while ( T-- ) { scanf("%d%d",&n,&m); memset(first,-1,sizeof(first)); cnt = 0; for ( int i = 1; i < n; ++i ) { scanf("%d%d",&u,&v); add(u,v); add(v,u); } memset(dep,0,sizeof(dep)); int res = 1; dfs(res,0,0); for ( int i = 2; i <= n; ++i ) if ( dep[i] > dep[res] ) res = i; dfs(res,0,0); int ans = 0,k; for ( int i = 1; i <= n; ++i ) if ( ans < dep[i] ) ans = dep[i]; ans++; for ( int i = 1; i <= m; ++i ) { scanf("%d",&k); if ( k <= ans ) printf("%d\n",k-1); else printf("%d\n",(k-ans)*2+ans-1); } } return 0;}
K - Cards(HDU 4610)
16种卡片,2^16种情况#include<iostream>#include<string.h>#include<string>#include<stdio.h>#include<algorithm>#define maxn 5000020#define N 5000010#define mm 50using namespace std;int pp[maxn+10],ge[75536];bool Isp[maxn];int you[mm],dan[50];int n,m,nn,cnt,K,ans;struct pai{ int x,z;}pi[mm];void Prim(){ memset(Isp,0,sizeof(Isp)); cnt = 0; Isp[1] = 1; for ( int i = 2; i < N; ++i ) if ( !Isp[i] ) for ( int j = 2; j * i < N; ++j ) Isp[i*j] = 1; for ( int i = 2; i < N; ++i ) if ( !Isp[i] ) pp[++cnt] = i;}bool conditions1( int x ){ if( !Isp[x] ) return 1; else return 0;}bool conditions2( int x ){ int gg =1,hh = 0; for ( int i = 1; pp[i] * pp[i] <= x ; ++i ) { if ( x % pp[i] == 0 ) { hh = 0; while ( x % pp[i] == 0 ) { ++hh; x /= pp[i]; } gg *= ( hh + 1 ); } } if ( x != 1 ) gg *= 2; if ( !Isp[gg] ) return 1; else return 0;}bool conditions3( int x ){ int gg = 1, hh = 0,nn; for ( int i = 1; pp[i] * pp[i] <= x; ++i ) { if ( x % pp[i] == 0 ) { hh = pp[i]; nn = 1; while ( x % pp[i] == 0 ) { nn += hh; hh *= pp[i]; x /= pp[i]; } gg *= nn; } } if( x != 1 ) gg *= ( x+ 1 ); if ( !Isp[gg] ) return 1; else return 0;}bool conditions4( int x ){ if( x == 1 ) return 1; int yz[40], cn=-1; bool flag; for( int i = 1; pp[i] * pp[i] <= x; i++ ) { if( x % pp[i] == 0 ) { int nn = 0; while( x % pp[i] == 0 ) { x /= pp[i]; nn++; } yz[++cn] = nn; } } if( x != 1 ) yz[++cn] = 1; for( int i = 0; i <= cn; i++ ) { if( yz[i] % 4 == 1 || yz[i] % 4 == 2 ) { flag = 0; for( int j = 0; j <= cn; j++ ) { if( j != i && yz[j] % 2 == 1 ) flag = 1; } if( flag == 0 ) return 0; } } return 1;}int cmp( pai p1, pai p2 ){ return p1.z > p2.z;}int main(){ int T; Prim(); for ( int i = 0; i < 16; ++i ) { pi[i].x = i; pi[i].z = 0; for ( int j = 0; j < 4; ++j ) if ( i & (1<<j) ) pi[i].z++; you[i] = pi[i].z; } sort(pi,pi+16,cmp); scanf("%d",&T); while ( T-- ) { scanf("%d%d",&n,&K); memset(ge,0,sizeof(ge)); int now = 0,a = 0, y = 0, x = 0,z = 0; for ( int i = 1; i <= n; ++i ) { scanf("%d%d",&x,&z); a = 0; y = 0; if ( conditions1(x) ) y |= 1; if ( conditions2(x) ) y |= 2; if ( conditions3(x) ) y |= 4; if ( conditions4(x) ) y |= 8; for ( int j = 0; j < 4; ++j ) if ( y & 1 << j ) ++a; if ( i == n ) printf("%d\n",a); else printf("%d ",a); ge[y] += z; } for ( int i = 0; i < 4 ; ++i ) scanf("%d",&dan[i]); for ( int i = 0; i < 16; ++i ) if ( ge[i] != 0 ) now |= 1<<i; ans = -1e9; for ( int i = 0; i < ( 1 << 16 ); ++i ) { int num = 0,res= 0, zhang = 0,gg; if ( i == ( i & now) ) { for ( int j = 0; j < 16; ++j ) if ( i & (1<<j) ) { ++num; res += you[j]; zhang = zhang | j; } if ( num > K ) continue; for ( int j = 0; j < 16; ++j ) if ( i & ( 1 << pi[j].x ) ) { gg = ge[pi[j].x]; --gg; gg = min(gg,K-num); num += gg; res += you[pi[j].x] * gg; } if ( num != K ) continue; for ( int j = 0; j <= 3 ; ++j ) if ( ( zhang & ( 1 << j ) )== 0 ) res += dan[j]; ans = max(ans,res); } } printf("%d\n",ans); } return 0;}
- 2013 Multi-University Training Contest 1
- 2013 Multi-University Training Contest 1
- 2013 Multi-University Training Contest 1
- 2013 Multi-University Training Contest 1
- 2013 Multi-University Training Contest 1 Occupy Cities HDU 4606
- 2013 Multi-University Training Contest 1 I-number 大数
- 2013 Multi-University Training Contest 1 Warm up HDU 4612
- 2013 Multi-University Training Contest 1 (hdu 4601 hdu 4603)
- 2013 Multi-University Training Contest 1——I-number
- 2013 Multi-University Training Contest 2
- 2013 Multi-University Training Contest 3
- 2013 Multi-University Training Contest 3
- 2013 Multi-University Training Contest 4
- 2013 Multi-University Training Contest 5
- 2013 Multi-University Training Contest 6
- 2013 Multi-University Training Contest 7
- 2013 Multi-University Training Contest 8
- 2013 Multi-University Training Contest 8 小结
- ORACLE PL/SQL编程之八:把触发器说透
- Poj 2533-Longest Ordered Subsequence(最长有序子序列)
- 函数
- axis WebServices 完美调用天气预报,查询、显示 代码!
- 接收字段的成员属性与接收数组参数的成员方法的进行反射
- 2013 Multi-University Training Contest 1
- 存储过程
- Ubuntu忘记root密码
- The Hound of the Baskervilles——8、The Stapletons of Pen House
- 在UITableView里面 定制滑动显示出来的 按钮的底色。
- Regexper.com 图解正则表达式
- GetDelicacies
- 对不对呢?
- linux内核:No oob scheme defined for oobsize 512