【HDU】2014上海全国邀请赛——题目重现(感谢上海大学提供题目) 题解
2014-11-02 18:45
465 查看
写在最前:感谢bin神~
A:【HDU】5090Game with Pearls
将所有的数扔到优先队列中,每次取出最小的+k,如果正好等于cur,cur++,如果+k>cur说明无解,否则+k以后扔进优先队列中继续,因为数很小所以随便搞就好了。
B:【HDU】5091Beam
Cannon
以每个点(x,y)作为宽w,高h的矩形的左下角,则答案即矩阵重叠次数最多的地方。我们可以这样:将每个矩阵拆成两条线段(x,x+w,y,1),(x,x+w,y+h,-1)(左端点,右端点,线段的高度,1表示进,-1表示出)。然后将线段按高度排序,高度相同的进的在前。然后题目就变成每遇到一条线段就区间加减,同时维护区间最大值。答案就是每条线段操作完后整个区间的最大值。线段树下标需要通过离散化宽度得到。
C:【HDU】5092Battle
ships
题意感觉不好理解。。本意就是数塔,对于点(i,j),只能到达(i+1,j-1),(i+1,j),(i+1,j+1)。然后求从第1层到第n层的和最小的路径(起点为第1层任意一个,终点为第n层任意一个),最后要求输出符合条件的路径尽量靠近右边的,那么我们递归输出,能往右走就往右走就好了。
D:【HDU】5093Battle
ships
二分图行列匹配= 、=。。行列重编号然后建边就好了,一行中每遇到一次障碍物就拆行,列同理。
E:【HDU】5094 Maze
状态压缩广搜,vis[x][y][S],(x,y)为坐标,S为当前拿到的钥匙的状态。注意一个位置可能有多把钥匙。
F:【HDU】5095Linearization
of the kernel functions in SVM
照着题意做就好。
H:【HDU】5097Page
Rank
对着方法构造出G矩阵,然后p向量初始值设为1,然后就用pnext = G*pcur不断迭代,直到pnext-pcur<1e-10为止,然后输出此时的pcur或pnext都可以。(因为答案只要求保留两位小数,那么我们不必按照题目说的求那么精确,1e-5就可以了,再大我的算法就WA了。。)
因为这个计算是一定收敛(也就是一定有解),且收敛速度飞快=、=所以这样暴力搞一点问题都没有。。。具体什么的还是自己查找一下吧,网上还是有关于这个的很多信息的。
(这题p向量初始值必须全1。。。题目有说明吗???)
I:【HDU】5098Smart
Software Installer
如果我们给有从属关系的两个设备建边(u,v)表示安装v前需先安装完成u。因为带*的重启后才安装完成,所以在一条有向路径上的所有带*设备要分别重启。于是我们给每个点一个点权,0表示这个点不需要重启,1表示这个点需要重启,于是我们建完图跑一遍DAG最长路就好了。题目已经说明此图是无环的了。
可能本题的难点不在发现这个题怎么写。。而在处理字符串上。。。。
J:【HDU】5099Comparison
of Android versions
第一个字符是版本号,第二个字符是这个版本的分支,接下来三个字符是时间,最后一个字符我也不知道是什么。
第一个输出为两个字符串的版本号的比较。
第二个输出为时间的比较,如果他们的分支相同时要带上最后一个字符一起比较,否则不带。比较的大小就是字符串大小的比较。
A:【HDU】5090Game with Pearls
将所有的数扔到优先队列中,每次取出最小的+k,如果正好等于cur,cur++,如果+k>cur说明无解,否则+k以后扔进优先队列中继续,因为数很小所以随便搞就好了。
#include <map> #include <string> #include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #pragma comment(linker, "/STACK:16777216") #define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define clr( a , x ) memset ( a , x , sizeof a ) #define ls ( o << 1 ) #define rs ( o << 1 | 1 ) #define lson ls , l , m #define rson rs , m + 1 , r #define root 1 , 1 , cnt #define mid ( ( l + r ) >> 1 ) const int MAXN = 105 ; const int MAXH = 1000005 ; struct queue { int heap[MAXH] ; int point ; void clear () { point = 1 ; } int empty () { return point == 1 ; } void maintain ( int o ) { int p = o , l = o << 1 , r = o << 1 | 1 ; while ( o > 1 && heap[o] < heap[o >> 1] ) { swap ( heap[o] , heap[o >> 1] ) ; o >>= 1 ; } o = p ; while ( 1 ) { if ( l < point && heap[l] < heap[p] ) p = l ; if ( r < point && heap[r] < heap[p] ) p = r ; if ( p == o ) break ; swap ( heap[o] , heap[p] ) ; o = p , l = o << 1 , r = o << 1 | 1 ; } } void push ( int d ) { heap[point] = d ; maintain ( point ++ ) ; } void pop () { heap[1] = heap[-- point] ; maintain ( 1 ) ; } int top () { return heap[1] ; } } ; queue q ; int a[MAXN] ; int n , k ; void solve () { int cur = 1 ; q.clear () ; scanf ( "%d%d" , &n , &k ) ; For ( i , 1 , n ) { scanf ( "%d" , &a[i] ) ; q.push ( a[i] ) ; } while ( cur <= n ) { int u = q.top () ; q.pop () ; if ( u > cur ) { printf ( "Tom\n" ) ; return ; } else if ( u == cur ) { ++ cur ; continue ; } else q.push ( u + k ) ; } printf ( "Jerry\n" ) ; } int main () { int T ; scanf ( "%d" , &T ) ; while ( T -- ) solve () ; return 0 ; }
B:【HDU】5091Beam
Cannon
以每个点(x,y)作为宽w,高h的矩形的左下角,则答案即矩阵重叠次数最多的地方。我们可以这样:将每个矩阵拆成两条线段(x,x+w,y,1),(x,x+w,y+h,-1)(左端点,右端点,线段的高度,1表示进,-1表示出)。然后将线段按高度排序,高度相同的进的在前。然后题目就变成每遇到一条线段就区间加减,同时维护区间最大值。答案就是每条线段操作完后整个区间的最大值。线段树下标需要通过离散化宽度得到。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #pragma comment(linker, "/STACK:16777216") #define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define clr( a , x ) memset ( a , x , sizeof a ) #define ls ( o << 1 ) #define rs ( o << 1 | 1 ) #define lson ls , l , m #define rson rs , m + 1 , r #define root 1 , 1 , cnt #define mid ( ( l + r ) >> 1 ) const int MAXN = 20005 ; struct Seg { int l , r , h , f ; Seg () {} Seg ( int l , int r , int h , int f ) : l ( l ) , r ( r ) , h ( h ) , f ( f ) {} bool operator < ( const Seg& a ) const { if ( h != a.h ) return h < a.h ; return f > a.f ; } } ; Seg L[MAXN << 1] ; int maxv[MAXN << 3] ; int addv[MAXN << 3] ; int a[MAXN] , cnt ; int n , w , h ; int unique ( int n ) { sort ( a + 1 , a + n + 1 ) ; int cnt = 1 ; For ( i , 2 , n ) if ( a[cnt] != a[i] ) a[++ cnt] = a[i] ; return cnt ; } int search ( int x , int l = 1 , int r = cnt ) { while ( l < r ) { int m = mid ; if ( a[m] >= x ) r = m ; else l = m + 1 ; } return l ; } void update ( int L , int R , int v , int o , int l , int r ) { if ( L <= l && r <= R ) { maxv[o] += v ; addv[o] += v ; return ; } if ( addv[o] ) { addv[ls] += addv[o] ; addv[rs] += addv[o] ; maxv[ls] += addv[o] ; maxv[rs] += addv[o] ; addv[o] = 0 ; } int m = mid ; if ( L <= m ) update ( L , R , v , lson ) ; if ( m < R ) update ( L , R , v , rson ) ; maxv[o] = max ( maxv[ls] , maxv[rs] ) ; } void solve () { int x , y , m ; m = cnt = 0 ; clr ( maxv , 0 ) ; clr ( addv , 0 ) ; scanf ( "%d%d" , &w , &h ) ; For ( i , 1 , n ) { scanf ( "%d%d" , &x , &y ) ; a[++ cnt] = x ; a[++ cnt] = x + w ; L[++ m] = Seg ( x , x + w , y , 1 ) ; L[++ m] = Seg ( x , x + w , y + h , -1 ) ; } int ans = 0 ; cnt = unique ( cnt ) ; sort ( L + 1 , L + m + 1 ) ; For ( i , 1 , m ) { int l = search ( L[i].l ) ; int r = search ( L[i].r ) ; update ( l , r , L[i].f , root ) ; ans = max ( ans , maxv[1] ) ; } printf ( "%d\n" , ans ) ; } int main () { while ( ~scanf ( "%d" , &n ) && ( n >= 0 ) ) solve () ; return 0 ; }
C:【HDU】5092Battle
ships
题意感觉不好理解。。本意就是数塔,对于点(i,j),只能到达(i+1,j-1),(i+1,j),(i+1,j+1)。然后求从第1层到第n层的和最小的路径(起点为第1层任意一个,终点为第n层任意一个),最后要求输出符合条件的路径尽量靠近右边的,那么我们递归输出,能往右走就往右走就好了。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #pragma comment(linker, "/STACK:16777216") #define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define clr( a , x ) memset ( a , x , sizeof a ) #define ls ( o << 1 ) #define rs ( o << 1 | 1 ) #define lson ls , l , m #define rson rs , m + 1 , r #define root 1 , 1 , cnt #define mid ( ( l + r ) >> 1 ) const int MAXN = 105 ; const int INF = 0x3f3f3f3f ; int dp[MAXN][MAXN] ; int a[MAXN][MAXN] ; int n , m ; void print ( int x , int y ) { if ( x > 1 ) { if ( y < m && dp[x - 1][y + 1] + a[x][y] == dp[x][y] ) print ( x - 1 , y + 1 ) ; else if ( dp[x - 1][y] + a[x][y] == dp[x][y] ) print ( x - 1 , y ) ; else print ( x - 1 , y - 1 ) ; } printf ( "%d%c" , y , x == n ? '\n' : ' ' ) ; } void solve () { clr ( dp , INF ) ; scanf ( "%d%d" , &n , &m ) ; For ( i , 1 , n ) For ( j , 1 , m ) scanf ( "%d" , &a[i][j] ) ; clr ( dp[0] , 0 ) ; For ( i , 1 , n ) For ( j , 1 , m ) { if ( j > 1 ) dp[i][j] = min ( dp[i][j] , dp[i - 1][j - 1] ) ; dp[i][j] = min ( dp[i][j] , dp[i - 1][j] ) ; if ( j < m ) dp[i][j] = min ( dp[i][j] , dp[i - 1][j + 1] ) ; dp[i][j] += a[i][j] ; } int minv = INF , pos ; For ( i , 1 , m ) if ( dp [i] <= minv ) { minv = dp [i] ; pos = i ; } print ( n , pos ) ; } int main () { int T , cas = 0 ; scanf ( "%d" , &T ) ; while ( T -- ) { printf ( "Case %d\n" , ++ cas ) ; solve () ; } return 0 ; }
D:【HDU】5093Battle
ships
二分图行列匹配= 、=。。行列重编号然后建边就好了,一行中每遇到一次障碍物就拆行,列同理。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #pragma comment(linker, "/STACK:16777216") #define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define clr( a , x ) memset ( a , x , sizeof a ) #define ls ( o << 1 ) #define rs ( o << 1 | 1 ) #define lson ls , l , m #define rson rs , m + 1 , r #define root 1 , 1 , cnt #define mid ( ( l + r ) >> 1 ) const int MAXN = 2505 ; const int MAXE = 2000000 ; struct Edge { int v , n ; Edge () {} Edge ( int v , int n ) : v ( v ) , n ( n ) {} } ; Edge E[MAXE] ; int H[MAXN] , cntE ; int vis[MAXN] , Time ; int R[55][55] , C[55][55] ; int row , col ; char G[55][55] ; int Lx[MAXN] , Ly[MAXN] ; int n , m ; void clear () { cntE = 0 ; clr ( H , -1 ) ; } void addedge ( int u , int v ) { E[cntE] = Edge ( v , H[u] ) ; H[u] = cntE ++ ; } int dfs ( int u ) { for ( int i = H[u] ; ~i ; i = E[i].n ) { int v = E[i].v ; if ( vis[v] == Time ) continue ; vis[v] = Time ; if ( Ly[v] == -1 || dfs ( Ly[v] ) ) { Ly[v] = u ; Lx[u] = v ; return 1 ; } } return 0 ; } int match () { int ans = 0 ; clr ( Lx , -1 ) ; clr ( Ly , -1 ) ; for ( int i = 1 ; i <= row ; ++ i ) { ++ Time ; ans += dfs ( i ) ; } return ans ; } void solve () { row = col = 0 ; clear () ; clr ( R , 0 ) ; clr ( C , 0 ) ; scanf ( "%d%d" , &n , &m ) ; For ( i , 1 , n ) scanf ( "%s" , G[i] + 1 ) ; For ( i , 1 , n ) { ++ row ; For ( j , 1 , m ) { if ( G[i][j] == '#' ) ++ row ; if ( G[i][j] == '*' ) R[i][j] = row ; } } For ( j , 1 , m ) { ++ col ; For ( i , 1 , n ) { if ( G[i][j] == '#' ) ++ col ; if ( G[i][j] == '*' ) C[i][j] = col ; } } //For ( i , 1 , n ) For ( j , 1 , m ) printf ( "%d%c" , C[i][j] , j < m ? ' ' : '\n' ) ; For ( i , 1 , n ) For ( j , 1 , m ) if ( G[i][j] == '*' ) addedge ( R[i][j] , C[i][j] ) ; printf ( "%d\n" , match () ) ; } int main () { int T ; scanf ( "%d" , &T ) ; while ( T -- ) solve () ; return 0 ; }
E:【HDU】5094 Maze
状态压缩广搜,vis[x][y][S],(x,y)为坐标,S为当前拿到的钥匙的状态。注意一个位置可能有多把钥匙。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #pragma comment(linker, "/STACK:16777216") #define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define clr( a , x ) memset ( a , x , sizeof a ) #define ls ( o << 1 ) #define rs ( o << 1 | 1 ) #define lson ls , l , m #define rson rs , m + 1 , r #define root 1 , 1 , cnt #define mid ( ( l + r ) >> 1 ) const int MAXN = 55 ; const int MAXQ = 3000000 ; struct Node { int d , x , y , s ; Node () {} Node ( int d , int x , int y , int s ) : d ( d ) , x ( x ) , y ( y ) , s ( s ) {} } ; Node Q[MAXQ] ; int head , tail ; int map[MAXN * MAXN][4] ; bool vis[MAXN][MAXN][1024] ; int G[MAXN][MAXN] ; int path[4][2] = { { 1 , 0 } , { -1 , 0 } , { 0 , 1 } , { 0 , -1 } } ;//dulr int n , m , p ; int bfs () { head = tail = 0 ; clr ( vis , 0 ) ; Q[tail ++] = Node ( 0 , 0 , 0 , 0 ) ; vis[0][0][0] = 1 ; while ( head != tail ) { Node now = Q[head ++] ; if ( now.x == n - 1 && now.y == m - 1 ) return now.d ; rep ( i , 0 , 4 ) { int nx = now.x + path[i][0] ; int ny = now.y + path[i][1] ; if ( nx < 0 || nx >= n || ny < 0 || ny >= m ) continue ; int tmp = map[now.x * m + now.y][i] ; if ( tmp == -2 ) continue ; if ( tmp >= 0 && !( tmp & now.s ) ) continue ; int ns = now.s | G[nx][ny] ; if ( vis[nx][ny][ns] ) continue ; vis[nx][ny][ns] = 1 ; Q[tail ++] = Node ( now.d + 1 , nx , ny , ns ) ; } } return -1 ; } void solve () { int k , x1 , x2 , y1 , y2 , g , f ; int tot = n * m ; clr ( map , -1 ) ; clr ( G , 0 ) ; scanf ( "%d" , &k ) ; rep ( i , 0 , k ) { scanf ( "%d%d%d%d%d" , &x1 , &y1 , &x2 , &y2 , &g ) ; -- x1 ; -- x2 ; -- y1 ; -- y2 ; if ( x1 < x2 ) f = 0 ; else if ( x1 > x2 ) f = 1 ; else if ( y1 < y2 ) f = 2 ; else f = 3 ; map[x2 * m + y2][f ^ 1] = map[x1 * m + y1][f] = ( g ? ( 1 << ( g - 1 ) ) : -2 ) ; } scanf ( "%d" , &k ) ; rep ( i , 0 , k ) { scanf ( "%d%d%d" , &x1 , &y1 , &g ) ; -- x1 ; -- y1 ; -- g ; G[x1][y1] |= ( 1 << g ) ; } printf ( "%d\n" , bfs () ) ; } int main () { while ( ~scanf ( "%d%d%d" , &n , &m , &p ) ) solve () ; return 0 ; }
F:【HDU】5095Linearization
of the kernel functions in SVM
照着题意做就好。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #pragma comment(linker, "/STACK:16777216") #define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define clr( a , x ) memset ( a , x , sizeof a ) int a[10] ; char s[11] = "pqruvwxyz" ; void solve () { int x , flag = 0 ; rep ( i , 0 , 10 ) { scanf ( "%d" , &x ) ; if ( x == 0 ) continue ; if ( x > 0 && flag ) printf ( "+" ) ; if ( !flag ) flag = 1 ; if ( x < 0 ) printf ( "-" ) ; if ( 1 != abs ( x ) ) printf ( "%d" , abs ( x ) ) ; if ( i == 9 && 1 == abs ( x ) ) printf ( "%d" , abs ( x ) ) ; if ( i < 9 ) printf ( "%c" , s[i] ) ; } if ( !flag ) printf ( "0" ) ; printf ( "\n" ) ; } int main () { int T ; scanf ( "%d" , &T ) ; while ( T -- ) solve () ; return 0 ; }
H:【HDU】5097Page
Rank
对着方法构造出G矩阵,然后p向量初始值设为1,然后就用pnext = G*pcur不断迭代,直到pnext-pcur<1e-10为止,然后输出此时的pcur或pnext都可以。(因为答案只要求保留两位小数,那么我们不必按照题目说的求那么精确,1e-5就可以了,再大我的算法就WA了。。)
因为这个计算是一定收敛(也就是一定有解),且收敛速度飞快=、=所以这样暴力搞一点问题都没有。。。具体什么的还是自己查找一下吧,网上还是有关于这个的很多信息的。
(这题p向量初始值必须全1。。。题目有说明吗???)
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #pragma comment(linker, "/STACK:16777216") #define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define clr( a , x ) memset ( a , x , sizeof a ) #define cpy( a , x ) memcpy ( a , x , sizeof a ) const int MAXN = 3005 ; const double eps = 1e-5 ; double G[MAXN][MAXN] ; double cur[MAXN] , next[MAXN] ; char buf[MAXN] ; int n ; inline int dcmp ( double x ) { return ( x > eps ) - ( x < -eps ) ; } bool check () { rep ( i , 0 , n ) if ( dcmp ( cur[i] - next[i] ) ) return 0 ; return 1 ; } void solve () { clr ( G , 0 ) ; clr ( cur , 0 ) ; clr ( next , 0 ) ; rep ( i , 0 , n ) next[i] = 1 ; rep ( i , 0 , n ) { scanf ( "%s" , buf ) ; int cnt = 0 ; rep ( j , 0 , n ) if ( buf[j] - '0' ) ++ cnt ; if ( cnt ) rep ( j , 0 , n ) if ( buf[j] - '0' ) G[j][i] = 0.85 / cnt ; rep ( j , 0 , n ) G[j][i] += 0.15 / n ; } while ( !check () ) { cpy ( cur , next ) ; rep ( i , 0 , n ) { next[i] = 0 ; rep ( j , 0 , n ) next[i] += G[i][j] * cur[j] ; } } rep ( i , 0 , n ) printf ( "%.2f%c" , next[i] , i < n - 1 ? ' ' : '\n' ) ; } int main () { while ( ~scanf ( "%d" , &n ) ) solve () ; return 0 ; }
I:【HDU】5098Smart
Software Installer
如果我们给有从属关系的两个设备建边(u,v)表示安装v前需先安装完成u。因为带*的重启后才安装完成,所以在一条有向路径上的所有带*设备要分别重启。于是我们给每个点一个点权,0表示这个点不需要重启,1表示这个点需要重启,于是我们建完图跑一遍DAG最长路就好了。题目已经说明此图是无环的了。
可能本题的难点不在发现这个题怎么写。。而在处理字符串上。。。。
#include <map> #include <string> #include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #pragma comment(linker, "/STACK:16777216") #define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define For( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define clr( a , x ) memset ( a , x , sizeof a ) #define ls ( o << 1 ) #define rs ( o << 1 | 1 ) #define lson ls , l , m #define rson rs , m + 1 , r #define root 1 , 1 , cnt #define mid ( ( l + r ) >> 1 ) const int MAXN = 1005 ; const int MAXE = 1000005 ; struct Edge { int v , n ; Edge () {} Edge ( int v , int n ) : v ( v ) , n ( n ) {} } ; Edge E[MAXE] ; int H[MAXN] , cntE ; int d[MAXN] , num[MAXN] ; int point ; char buf[10000] , s[10000] ; int in[MAXN] ; int Q[MAXN] , head , tail ; map < string , int > mp ; void clear () { cntE = 0 ; point = 0 ; mp.clear () ; clr ( in , 0 ) ; clr ( H , -1 ) ; clr ( num , 0 ) ; } void addedge ( int u , int v ) { E[cntE] = Edge ( v , H[u] ) ; H[u] = cntE ++ ; } void topo () { clr ( d , 0 ) ; head = tail = 0 ; for ( int i = 1 ; i <= point ; ++ i ) if ( !in[i] ) { Q[tail ++] = i ; d[i] = num[i] ; } while ( head != tail ) { int u = Q[head ++] ; for ( int i = H[u] ; ~i ; i = E[i].n ) { int v = E[i].v ; if ( d[v] < d[u] + num[v] ) d[v] = d[u] + num[v] ; if ( 0 == -- in[v] ) Q[tail ++] = v ; } } int ans = 0 ; for ( int i = 1 ; i <= point ; ++ i ) ans = max ( ans , d[i] ) ; printf ( "%d\n" , ans ) ; } void solve () { int u , v ; clear () ; while ( 1 ) { if ( !gets ( buf ) ) break ; if ( !buf[0] ) break ; int cnt = 0 , i ; for ( i = 0 ; buf[i] != ':' ; ++ i ) if ( buf[i] != '*' ) s[cnt ++] = buf[i] ; s[cnt] = 0 ; if ( !mp.count ( s ) ) u = mp[s] = ++ point ; else u = mp[s] ; if ( buf[i - 1] == '*' ) num[u] = 1 ; cnt = 0 ; if ( buf[i + 1] == 0 ) continue ; for ( i += 2 ; buf[i] ; ++ i ) { if ( buf[i] == ' ' || !buf[i + 1] ) { if ( buf[i + 1] == 0 ) s[cnt ++] = buf[i] ; s[cnt] = 0 ; if ( !mp.count ( s ) ) v = mp[s] = ++ point ; else v = mp[s] ; addedge ( v , u ) ; ++ in[u] ; cnt = 0 ; } else s[cnt ++] = buf[i] ; } } topo () ; } int main () { int T , cas = 0 ; scanf ( "%d" , &T ) ; getchar () ; getchar () ; while ( T -- ) { printf ( "Case %d: " , ++ cas ) ; solve () ; } return 0 ; }
J:【HDU】5099Comparison
of Android versions
第一个字符是版本号,第二个字符是这个版本的分支,接下来三个字符是时间,最后一个字符我也不知道是什么。
第一个输出为两个字符串的版本号的比较。
第二个输出为时间的比较,如果他们的分支相同时要带上最后一个字符一起比较,否则不带。比较的大小就是字符串大小的比较。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; char s1[7] , s2[7] ; void solve () { scanf ( "%s%s" , s1 , s2 ) ; if ( s1[0] > s2[0] ) printf ( ">" ) ; else if ( s1[0] == s2[0] ) printf ( "=" ) ; else printf ( "<" ) ; printf ( " " ) ; if ( s1[0] != s2[0] || s1[1] != s2[1] ) s1[5] = s2[5] = 0 ; int cmp = strcmp ( s1 + 2 , s2 + 2 ) ; if ( cmp < 0 ) printf ( "<" ) ; else if ( cmp == 0 ) printf ( "=" ) ; else printf ( ">" ) ; printf ( "\n" ) ; } int main () { int T , cas = 0 ; scanf ( "%d" , &T ) ; while ( T -- ) { printf ( "Case %d: " , ++ cas ) ; solve () ; } return 0 ; }
相关文章推荐
- HDU 5097 Page Rank(矩阵模拟)——2014上海全国邀请赛——题目重现(感谢上海大学提供题目)
- hdu 5092 Seam Carving 2014上海全国邀请赛——题目重现
- hdu 5090 Game with Pearls 2014上海全国邀请赛——题目重现
- 2014西安全国邀请赛——题目重现(感谢西工大+复旦)HDOJ4847 Wow! Such Doge!
- 2014西安全国邀请赛——题目重现(感谢西工大+复旦 HDOJ 4849 Wow! Such City!
- 2014上海全国邀请赛——题目重现 4.24
- HDU5092 Seam Carving(2014上海全国邀请赛——题目重现)(DP)
- hdu 4497 GCD and LCM(2013 ACM-ICPC吉林通化全国邀请赛——题目重现)
- hdu 4585 Shaolin 2013 ACM-ICPC杭州赛区全国邀请赛——题目重现
- HDU5093——Battle ships(最大二分匹配)(2014上海邀请赛重现)
- hdu 4576 robot 2013 ACM-ICPC杭州赛区全国邀请赛——题目重现-1001-robot
- HDU5092——Seam Carving(动态规划+回溯)(2014上海邀请赛重现)
- hdu 4497 GCD and LCM(2013 ACM-ICPC吉林通化全国邀请赛——题目重现)
- 2014上海全国邀请赛1003(hdu 5092)
- 2014上海全国邀请赛1010(hdu 5099)
- hdu 4585 Shaolin 2013 ACM-ICPC杭州赛区全国邀请赛——题目重现
- HDU_2013 ACM-ICPC南京赛区全国邀请赛——题目重现
- 2014上海全国邀请赛(hdu 5090 - 5099)dp+线段树+拓扑排序+bfs(状态压缩)
- 2014上海全国邀请赛1001(hdu 5090)
- HDU5099——Comparison of Android versions(简单题)(2014上海邀请赛重现)