2011 Spring Trainning Contest SLPC
来源:互联网 发布:网络买车 编辑:程序博客网 时间:2024/05/24 06:57
额,几天没来博客了,得写点东西……
先说上周六的这场比赛。
又是水过了简单题目,稍微难的就没有想出,然后其他题目又懒得看了……
这其实是学长挂的组队赛的,题目不算很难(因为我总感觉我能做出来的就是简单题目,事实上一直如此),大部分单个人参赛的都A掉了4、5道题目,而HIT_IF、HITDPS则A掉了11道,差一道AK……两个好牛的队伍啊……
水了,水了,这不是正解。正解是枚举三个的量。。。
先说上周六的这场比赛。
又是水过了简单题目,稍微难的就没有想出,然后其他题目又懒得看了……
这其实是学长挂的组队赛的,题目不算很难(因为我总感觉我能做出来的就是简单题目,事实上一直如此),大部分单个人参赛的都A掉了4、5道题目,而HIT_IF、HITDPS则A掉了11道,差一道AK……两个好牛的队伍啊……
先将我A掉的题目的题解写一下:(有点废话,没A掉怎么会写题解)
HOJ 2999 AAAAHH!Overbooked!
大水题第一:给了n条线段(开区间),求有木有两条线段有重叠部分。
排序,然后检查即可。
排序,然后检查即可。
#include <iostream>#define N 110using 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[N];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列数,对每列数进行排序,使得每行数相乘后的和最大。然后我就都按从小到大排了,应该有个证明最大数乘最大数、第二大乘第二大……最小乘最小,最终的和最大。
给了n行m列数,对每列数进行排序,使得每行数相乘后的和最大。然后我就都按从小到大排了,应该有个证明最大数乘最大数、第二大乘第二大……最小乘最小,最终的和最大。
#include <iostream>#define N 100using namespace std;double a[N][N];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掉了。
坑爹啊。。。。
很朴素的横坐标逐一检查即可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 100100using namespace std;int a[N];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。。。
代码很长很夸张。。。。
给了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 1100using 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 啊,你手下败将能打败的就算败给你啦。。。就看你能搞定的人能不能搞定其他人拉。。有木有啊。。。。
池子法啊,有木有啊。。。。
DFS 啊,你手下败将能打败的就算败给你啦。。。就看你能搞定的人能不能搞定其他人拉。。有木有啊。。。。
池子法啊,有木有啊。。。。
#include <iostream>#define N 100100#define M 100100#define K Nusing namespace std;int visit[N],tot;int fri[K];struct edge_data{ int v; edge_data*next;}*adj[N],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啦。。。。
随便找一点作为根进行深搜,最远的节点再作为根,再深搜,这次又得到一个最远节点,两次最远节点路上的点就是特么要修的高速公路啊。。。然后从高速公路上每个点向非高速公路上的点深搜,找一个最远距离就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 510using 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[N];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;}
- 2011 Spring Trainning Contest SLPC
- POJ Contest - ACM Trainning
- About Contest and Trainning
- TRAINNING
- NBUT 2015 ACM Trainning Contest-11038 Problem A How many Points 解题报告
- HCPC 2011 Spring Online Contest解题报告
- summer trainning...
- New Staff Outdoor Trainning
- KUKA Robot Trainning
- Linux trainning notes
- Trainning 小心得
- webservice trainning plan
- android trainning(4)
- EMC trainning杂谈
- trainning 2017-11-21
- 半监督分类算法简述,self-trainning,co-trainning
- Movex trainning-course 1summary
- State,Memento,Command Patterns Trainning
- Mac系统下显示隐藏文件
- pull解析实例
- Windows 不能在 本地计算机 启动 Distributed Transaction Coordinator .
- Xcode中下载和使用离线文档
- apache(单机)负载均衡配置(九)
- 2011 Spring Trainning Contest SLPC
- 64为WIN7 odbc配置
- linux kernel 学习之进程
- 简谈基于NGN-IMS(SIP协议)通信平台融入视频监控业务
- ORACLE如何kill掉session
- JAVA Expection 异常 笔记整理
- ASP.NET中页面及用户控件的事件执行顺序
- Gson的簡單使用
- HTTP AUTH 那些事