2011 Spring Trainning Contest SLPC
2012-02-14 17:15
78 查看
额,几天没来博客了,得写点东西……
先说上周六的这场比赛。
又是水过了简单题目,稍微难的就没有想出,然后其他题目又懒得看了……
这其实是学长挂的组队赛的,题目不算很难(因为我总感觉我能做出来的就是简单题目,事实上一直如此),大部分单个人参赛的都A掉了4、5道题目,而HIT_IF、HITDPS则A掉了11道,差一道AK……两个好牛的队伍啊……
先将我A掉的题目的题解写一下:(有点废话,没A掉怎么会写题解)
排序,然后检查即可。
给了n行m列数,对每列数进行排序,使得每行数相乘后的和最大。然后我就都按从小到大排了,应该有个证明最大数乘最大数、第二大乘第二大……最小乘最小,最终的和最大。
坑爹啊。。。。
很朴素的横坐标逐一检查即可A掉,不过数据不厚道,竟然不是以3个0结尾,所以搞得我一直超时,想各种优化,差点就打表了。。。后来还是交了一个O(sqrt(n))的算法A掉了。
给了n个菱形,每个菱形都是由2个带有数字的等边三角形组成,选取一部分拼接到一起,使得相邻菱形相邻的三角形数字相同。求最大的公共边。
n的范围很小,只有6.所以算法的复杂度可以很大,关键是不好下手写这个搜索。先写了1个任意填充,最后检查的,以WA或者TLE宣告失败,然后重写了个边检查边放的,结果太杂乱,运行结果错误,也不容易debug,而宣告失败。今天再次改变策略,不管是否会重复搜索,都搜索一下,最终一0.03s宣告AC。。。
代码很长很夸张。。。。
水了,水了,这不是正解。正解是枚举三个的量。。。
DFS 啊,你手下败将能打败的就算败给你啦。。。就看你能搞定的人能不能搞定其他人拉。。有木有啊。。。。
池子法啊,有木有啊。。。。
随便找一点作为根进行深搜,最远的节点再作为根,再深搜,这次又得到一个最远节点,两次最远节点路上的点就是特么要修的高速公路啊。。。然后从高速公路上每个点向非高速公路上的点深搜,找一个最远距离就over啦。。。。
算是一道难题吧。。。。
先说上周六的这场比赛。
又是水过了简单题目,稍微难的就没有想出,然后其他题目又懒得看了……
这其实是学长挂的组队赛的,题目不算很难(因为我总感觉我能做出来的就是简单题目,事实上一直如此),大部分单个人参赛的都A掉了4、5道题目,而HIT_IF、HITDPS则A掉了11道,差一道AK……两个好牛的队伍啊……
先将我A掉的题目的题解写一下:(有点废话,没A掉怎么会写题解)
HOJ 2999 AAAAHH!Overbooked!
大水题第一:给了n条线段(开区间),求有木有两条线段有重叠部分。排序,然后检查即可。
#include <iostream> #define N 110 using namespace std; struct data { int start,end; void input() { int st1,st2,en1,en2; scanf("%d:%d-%d:%d", &st1, &st2, &en1, &en2); start=st1*100+st2; end=en1*100+en2; } bool operator< (const data b)const { return start<b.start; } }p ; int main() { int n,i; bool flag; while(scanf("%d",&n),n) { for(i=0;i<n;i++) p[i].input(); sort(p,p+n); flag=true; for(i=0;flag&&i<n-1;i++) if(p[i+1].start<p[i].end)flag=false; if(!flag)puts("conflict"); else puts("no conflict"); } return 0; }
HOJ 3000 Betting Sets
额,这道题是大水题第二,凭感觉这么做,但不知道具体的证明。给了n行m列数,对每列数进行排序,使得每行数相乘后的和最大。然后我就都按从小到大排了,应该有个证明最大数乘最大数、第二大乘第二大……最小乘最小,最终的和最大。
#include <iostream> #define N 100 using namespace std; double a ; int main() { int n,m,i,j; double ans,p; while(scanf("%d %d",&n,&m),n||m) { ans=0; for(i=0;i<n ;i++) for(j=0;j<m;j++) scanf("%lf",a[j]+i); for(i=0;i<m;i++) sort(a[i],a[i]+n); for(i=0;i<n;i++) { p=1; for(j=0;j<m;j++) p*=a[j][i]; ans+=p; } printf("%.4lf\n",ans); } return 0; }
HOJ 3001 Counting Pixels
大坑爹题第一。。。坑爹啊。。。。
很朴素的横坐标逐一检查即可A掉,不过数据不厚道,竟然不是以3个0结尾,所以搞得我一直超时,想各种优化,差点就打表了。。。后来还是交了一个O(sqrt(n))的算法A掉了。
#include <iostream> #include <math .h> using namespace std; int main() { long long x,y,r,p,k,i; while(scanf("%lld %lld %lld",&x,&y,&r)==3&&(x||y||r)) { if(r==1) { puts("4"); continue; } k=0; for(i=r-1;i>0;i--) { p=(long long)ceil(sqrt(r*r-i*i)); if(p< =i)k+=p; if(p>=i) { k< <=1; k+=p*p; break; } } k*=4; printf("%lld\n",k); } return 0; }
HOJ 3002 Matryoshka Dolls
大水题第三。。。。 题目大概意思是关于套娃的。。。。一层套一层。。。 做法就是求出相同型号的个数的最大值。#include <iostream> #define N 100100 using namespace std; int a ; int main() { int n,i,tot,ans; while(scanf("%d",&n),n) { ans=0; tot=1; for(i=0;i<n ;i++) scanf("%d",a+i); sort(a,a+n); for(i=1;i<n;i++) { if(a[i]==a[i-1])tot++; else { if(tot>ans)ans=tot; tot=1; } } if(tot>ans)ans=tot; printf("%d\n",ans); } return 0; }
HOJ 3003 Equilateral Dominoes
这个题还是不错。给了n个菱形,每个菱形都是由2个带有数字的等边三角形组成,选取一部分拼接到一起,使得相邻菱形相邻的三角形数字相同。求最大的公共边。
n的范围很小,只有6.所以算法的复杂度可以很大,关键是不好下手写这个搜索。先写了1个任意填充,最后检查的,以WA或者TLE宣告失败,然后重写了个边检查边放的,结果太杂乱,运行结果错误,也不容易debug,而宣告失败。今天再次改变策略,不管是否会重复搜索,都搜索一下,最终一0.03s宣告AC。。。
代码很长很夸张。。。。
#include <stdio .h> const int M = 100; const int N = 6; int ans , n ; struct data { int right, left; bool used; void input() { scanf("%d %d", &right, &left); used = false; } } p[ N ]; struct data_map { int x, y, color, is_to_set, tot_filled; bool filled; data_map& neighbor( int ); void init( int i, int j ) { x = i; y = j; filled = false; } bool check() { is_to_set = -1; tot_filled = 0; for( int i = 0 ; i < 3 ; i ++ ) { if( neighbor( i ).filled ) { tot_filled ++; if( is_to_set == -1 ) is_to_set = neighbor( i ).color; else if( is_to_set != neighbor( i ).color ) return false; } } return true; } bool check_color( int col ) { if( is_to_set == -1 ) return true; return col == is_to_set; } void inque( int col ,int tail ); void outque() { filled = false; color = 0; } } map[ M ][ M ], *que[ M * M ]; data_map& data_map::neighbor(int k) { if( k == 0 ) return map[ x ][ y - 1 ]; if( k == 1 ) return map[ x ][ y + 1 ]; if( ( x ^ y ) & 1 ) return map[ x + 1 ][ y ]; return map[ x - 1 ][ y ]; } void data_map::inque( int col ,int tail ) { filled = true; color = col; que[ tail ] = this; } void dfs(int tail, int num) { if( num > ans ) { ans = num;/* for( int i = 0 ; i < 40 ; i ++ ) for( int j = 0 ; j < 40 ; j ++ ) { printf("%d " , map[ i ][ j ].color); if( j == 39 ) puts(""); } puts("");*/ } for( int i = 0 ; i < n ; i ++ ) { if( !p[ i ].used ) { for( int j = 0 ; j < tail ; j ++ ) { data_map &pos = *que[ j ]; if( pos.color == p[ i ].right || pos.color == p[ i ].left ) { for( int k = 0 ; k < 3 ; k ++ ) { data_map &new_pos = pos.neighbor( k ); if( !new_pos.filled && new_pos.check() ) { for( int l = 0 ; l < 3 ; l ++ ) { data_map &neigh = new_pos.neighbor( l ); if( !neigh.filled && neigh.check() ) { if( new_pos.check_color( p[ i ].right ) && neigh.check_color( p[ i ].left ) ) { new_pos.inque( p [ i ].right , tail ); neigh.inque( p[ i ].left , tail + 1); p[ i ].used = true; dfs( tail + 2 , new_pos.tot_filled + neigh.tot_filled + num ); p[ i ].used = false; new_pos.outque(); neigh.outque(); } else if(new_pos.check_color( p[ i ].left ) && neigh.check_color( p[ i ].right ) ) { new_pos.inque( p [ i ].left , tail ); neigh.inque( p[ i ].right , tail + 1); p[ i ].used = true; dfs( tail + 2 , new_pos.tot_filled + neigh.tot_filled + num ); p[ i ].used = false; new_pos.outque(); neigh.outque(); } } } } } } } } } } // 十个括号套着呢啊,有木有啊。。。。 int main() { while( scanf("%d", &n ), n ) { for( int i = 0 ; i < n ; i ++ ) { p[ i ].input(); } for( int i = 0 ; i < M ; i ++ ) for( int j = 0 ; j < M ; j ++ ) map[ i ][ j ].init( i , j ); ans = 0; for( int i = 0 ; i < n ; i ++ ) { p[ i ].used = true; map[ 20 ][ 20 ].inque( p[ i ].right , 0 ); map[ 20 ][ 21 ].inque( p[ i ].left , 1 ); dfs( 2 , 0 ); map[ 20 ][ 20 ].outque(); map[ 20 ][ 21 ].outque(); p[ i ].used = false; } printf("%d\n", ans); } return 0; }
HOJ 3004 Four Gate Push
二维背包问题,题目还是拐了下弯,你还得先除以25、50,然后再背包,这样内存才够。。。#include <iostream> #define M 2100 #define G 1100 using namespace std; int f[M][G]; int main() { int m,g,z,s,e,i,j; while(scanf("%d %d %d %d %d",&m,&g,&z,&s,&e),m||g||z||s||e) { memset(f,0,sizeof(f)); m/=25; g/=50; for(i=4;i< =m;i++) for(j=0;j<=g;j++) f[i][j]=max(f[i][j],f[i-4][j]+z); for(i=5;i<=m;i++) for(j=1;j<=g;j++) f[i][j]=max(f[i][j],f[i-5][j-1]+s); for(i=2;i<=m;i++) for(j=2;j<=g;j++) f[i][j]=max(f[i][j],f[i-2][j-2]+e); printf("%d\n",f[m][g]); } return 0; }
水了,水了,这不是正解。正解是枚举三个的量。。。
#include <iostream> using namespace std; int main() { int n, g, z, s, e, i, j, k; while(scanf("%d %d %d %d %d",&n, &g, &z, &s, &e ), n | g | z | s | e ) { int ans = 0; for( k = 0 ; k * 50 < = n && k * 100 <= g; k ++ ) for( j = 0 ; j * 125 + k * 50 <= n && j * 50 + k * 100 <= g ; j ++ ) { i = ( n - j * 125 - k * 50 ) / 100; ans = max( ans , i * z + j * s + k * e ); } printf("%d\n",ans); } return 0; }
HOJ 3005 Game Rigging
知道一部分人对决的胜负情况,能否让某些人中有一个人取胜。DFS 啊,你手下败将能打败的就算败给你啦。。。就看你能搞定的人能不能搞定其他人拉。。有木有啊。。。。
池子法啊,有木有啊。。。。
#include <iostream> #define N 100100 #define M 100100 #define K N using namespace std; int visit ,tot; int fri[K]; struct edge_data { int v; edge_data*next; }*adj ,edge[M]; void pushedge(int a,int b) { edge[tot].v=b; edge[tot].next=adj[a]; adj[a]=&edge[tot++]; } void dfs(int k) { visit[k]=1; edge_data *temp=adj[k]; while(temp) { if(!visit[temp->v])dfs(temp->v); temp=temp->next; } } int main() { int n,m,k,i,a,b; while(scanf("%d %d %d",&n,&k,&m),n||m||k) { memset(visit,0,sizeof(visit)); memset(adj,0,sizeof(adj)); tot=0; for(i=0;i<k ;i++) scanf("%d",fri+i); for(i=0;i<m;i++) { scanf("%d %d",&a,&b); pushedge(a,b); } for(i=0;i<k;i++) if(!visit[fri[i]])dfs(fri[i]); for(i=0;i<n;i++) if(!visit[i+1])break; if(i==n)puts("yes"); else puts("no"); } return 0; }
HOJ 3006 Highway Construction
当时没看懂题啊,原来是求数的直径啊,大水题啊,有木有啊。。。随便找一点作为根进行深搜,最远的节点再作为根,再深搜,这次又得到一个最远节点,两次最远节点路上的点就是特么要修的高速公路啊。。。然后从高速公路上每个点向非高速公路上的点深搜,找一个最远距离就over啦。。。。
#include <stdio .h> #include <string .h> const int N = 100100; struct data_edge { int v,w; data_edge *next; }*adj[ N ], edge[ N < < 1 ]; int visit[ N ], online[ N ], father[ N ]; int n, maxdeep, findk, tot_edge; void push_edge( int u,int v,int w) { edge[ tot_edge ].v = v; edge[ tot_edge ].w = w; edge[ tot_edge ].next = adj[ u ]; adj[ u ] = &edge[ tot_edge ++ ]; } void init() { memset( adj , 0 , sizeof( adj ) ); tot_edge = 0; for( int i = 0 ; i < n - 1 ; i ++ ) { int a,b,w; scanf("%d %d %d", &a, &b, &w); push_edge(a, b, w); push_edge(b, a, w); } } void dfs(int k, int deep) { visit[ k ] = 1; data_edge *temp = adj[ k ]; while( temp ) { if( !visit[ temp->v ]) { father[ temp->v ] = k; dfs( temp->v , deep + temp->w); } temp = temp->next; } if( deep > maxdeep) { maxdeep = deep; findk = k; } } void solve() { maxdeep = 0; memset(visit , 0 ,sizeof( visit )); dfs( 1 , 0 ); memset(visit , 0 ,sizeof( visit )); int firstk = findk; maxdeep = 0; dfs( findk , 0 ); memset(visit , 0 ,sizeof( visit )); memset(online , 0 ,sizeof( online )); int lastk = findk; while( lastk != firstk ) { visit[ lastk ] = 1; online[ lastk ] = 1; lastk = father[ lastk ]; } online[ lastk ] = 1; visit[ lastk ] = 1; maxdeep = 0; for( int i = 1 ; i < = n ; i++ ) if( online[ i ] ) dfs( i , 0 ); printf("%d\n",maxdeep); } int main() { while(scanf("%d", &n) , n) { init(); solve(); } return 0; }
HOJ 3008 Matryoshka Dolls, Again
坑爹啊,上面某道题的加强版啊,然后就变成匹配啦。。。。当时还拿搜索做来着,超时啊。。。。后来用匈牙利算法。。。强大啊。。。算是一道难题吧。。。。
#include <iostream> #define N 510 using namespace std; int f[ N ], ans, n, tot_edge, visit[ N ], match[ N ]; struct data { int x,y,z; void input() { scanf("%d %d %d",&x,&y,&z); } bool operator< (data b) { return x<b.x&&y<b.y&&z<b.z; } }p ; struct edge_data { int v; edge_data*next; }edge[ N * N ], *adj[ N ]; void push_edge(int u,int v) { edge[ tot_edge ].v = v; edge[ tot_edge ].next = adj[ u ]; adj[ u ] = &edge[ tot_edge++ ]; } void input() { tot_edge = 0; memset( adj , 0 , sizeof( adj ) ); int i,j; for ( i = 0 ; i < n ; i++) p[ i ].input(); for ( i = 0 ; i < n ; i++) for ( j = 0 ; j < n ; j++) if (p[ i ] < p[ j ]) push_edge( i, j ); } bool dfs( int k ) { edge_data *temp=adj[ k ]; while( temp ) { if( !visit[ temp->v ]) { visit[ temp->v ] = 1; if( match[ temp->v ] == -1 || dfs( match[ temp-> v ] ) ) { match[ temp->v ] = k; return true; } } temp = temp->next; } return false; } void solve() { int ans = 0; memset( match , -1 , sizeof( match ) ); for ( int i = 0 ; i < n ; i++) { memset( visit , 0 , sizeof( visit ) ); if ( dfs( i ) ) ans++; } printf("%d\n", n - ans ); } int main() { while (scanf("%d",&n),n) { input(); solve(); } return 0; }
相关文章推荐
- HCPC 2011 Spring Online Contest解题报告
- Zoj 3541 The Last Puzzle (dp) - 2011 ACM-ICPC Dalian Regional Contest Problem C
- CSU 1855: Shut the Box 状压BFS(2011 Mid-Central USA Regional Contest)
- NBUT 2015 ACM Trainning Contest-11038 Problem A How many Points 解题报告
- Sichuan University Programming Contest 2011 Preliminary(for Non-SCUers) / B The Weight of Tree
- 2011 Heilongjiang collegiate programming contest训练总结【10/10】
- Hdu 3936 FIB Query[矩阵快速幂](2011 Multi-University Training Contest 10 - Host by HRBEU)
- 2011 Asia Fuzhou Regional Contest-1001 hdu4121 Xiangqi
- C. Explode 'Em All 搜索 2010-2011 ACM-ICPC, NEERC, Southern Subregional Contest
- 2011 Multi-University Training Contest 1 - Host by HNU
- HDU HDU 3861 The King’s Problem 2011 Multi-University Training Contest 3 - Host by BIT
- HDU - 4054 Hexadecimal View (2011 Asia Dalian Regional Contest)
- HDU 3902 Swordsman 2011 Multi-University Training Contest 7 - Host by ECNU 计算几何
- 2013 国庆第一场(The 2011 Rocky Mountain Regional Contest)
- 2011-2012 Winter Petrozavodsk Camp, Andrew Stankevich Contest 41 (ASC 41)——莫队算法——Data Mining
- Sichuan University Programming Contest 2011 Preliminary(for Non-SCUers) / B The Weight of Tree
- 2011 Asia Beijing Regional Online Contest-1006 hdu4045 Machine scheduling
- BUPT Spring Ranking Contest For 13 Round #4 graph
- Gym 101246(ACM ICPC 2010-2011, NEERC, Southern Subregional Contest Russia, Saratov)
- HDU3832 Earth Hour 2011 Multi-University Training Contest 1 - Host by HNU