noip 2015 提高组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了noip 2015 提高组相关的知识,希望对你有一定的参考价值。

算是填个坑吧 , QwQ

Day 1

第一题很水,就是考代码能力 ,直接贴代码。

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 const int inf = 1 << 30 , maxn = 45 ;
 5 using namespace std ;
 6 int n , jv[maxn][maxn] ;
 7 inline void Init( )
 8 {
 9     freopen( "magic.in" , "r" , stdin ) ;
10     freopen( "magic.out" , "w" , stdout ) ;
11 }
12 
13 int read( )
14 {
15     char ch = getchar( ) ; int k = 1 , ret = 0 ;
16     while( ch < 0 || ch > 9 ) { if( ch == - )k = -1 ; ch = getchar( ) ; }
17     while( ch >= 0 && ch <= 9 ) ret = ret * 10 + ch - 0 , ch = getchar( ) ;
18     return ret * k ;
19 }
20 
21 
22 void sov(  )
23 {
24     int x = 1 , y = (1+n)>>1 ;
25     jv[x][y] = 1 ; 
26     for( int i = 2 ; i <= n*n ; ++i )
27     {
28         if( x == 1 && y != n )
29         {
30             jv[n][y+1] = i ;
31             x = n ; ++y ;
32             continue ;
33         }
34         if( y == n && x != 1 )
35         {
36             jv[x-1][1] = i ;
37             --x ; y = 1 ;
38             continue ;
39         }
40         if( x == 1 && y == n )
41         {
42             jv[x+1][y] = i ;
43             ++x ; continue ;
44         }
45         else
46         {
47             if( !jv[x-1][y+1] ) 
48             {
49                 jv[x-1][y+1] = i ;
50                 --x ; ++y ;
51                 continue ;
52             }
53             jv[x+1][y] = i ;
54             ++x ; continue ;
55         }
56     }
57 }
58 
59 void output( )
60 {
61     for( int x = 1 ; x <= n ; ++x )
62     {
63         for( int y = 1 ; y <= n ; ++y )    
64             printf( "%d " , jv[x][y] ) ;
65         printf( "\n" ) ;
66     }
67 }
68 
69 
70 int main( )
71 {    
72     Init( ) ; 
73     n = read( ) ;
74     sov( ) ;
75     output( ) ;
76     fclose( stdin ) ;
77     fclose( stdout ) ;
78     return 0 ;
79 }

第二题 

就是求一个有向图的最小正环 , 但分析后就知道每个点只有一个初度 ,所以图中只存在简单环 ,

于是我在考场上用并查集做的 。

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 const int inf = 1 << 30 , maxn =  200000 + 11  ;
 5 using namespace std ;
 6 int n , fa[maxn][2] ; //father and dis
 7 
 8 inline void Init( )
 9 {
10     freopen( "message.in" , "r" , stdin ) ;
11     freopen( "message.out" , "w" , stdout ) ;
12 }
13 
14 int read( )
15 {
16     char ch = getchar( ) ; int k = 1 , ret = 0 ;
17     while( ch < 0 || ch > 9 ) { if( ch == - )k = -1 ; ch = getchar( ) ; }
18     while( ch >= 0 && ch <= 9 ) ret = ret * 10 + ch - 0 , ch = getchar( ) ;
19     return ret * k ;
20 }
21 
22 int find( int x )
23 {
24     if( fa[x][0] == x ) return x ;
25     int fu = fa[x][0] ;
26     fa[x][0] = find( fa[x][0] ) ;
27     fa[x][1] += fa[fu][1] ;
28     return fa[x][0] ;
29 }
30 
31 
32 void sov( ) 
33 {
34     for( int x = 1 ; x <= n ; ++x ) fa[x][0] = x ;
35     int y , root1 , root2 , ans = inf ; 
36     for( int x = 1 ; x <= n ; ++x )
37     {
38         y = read( ) ;
39         root1 = find( x ) , root2 = find( y ) ;
40         if( root1 != root2 )
41         {
42             fa[root1][0] = root2 ;
43             fa[root1][1] += 1 + fa[y][1] ;
44         }
45         else 
46             ans = min( ans , fa[x][1] + fa[y][1] + 1 ) ;
47     }
48     printf( "%d\n" , ans ) ;
49 }
50 
51 
52 int main( )
53 {    
54     Init( ) ; 
55     n = read( ) ;
56     sov( ) ;
57     fclose( stdin ) ;
58     fclose( stdout ) ;
59     return 0 ;
60 }

后面是先拓扑去不是环里的点,在找最小的环(对每个点打标记,打个标记的点不用遍历。)

 1 #include <iostream>
 2 #include <cstdlib>
 3 #include <cstdio>
 4 #include <queue>
 5 const int inf = 1 << 30 , maxn =  200000 + 11  ;
 6 using namespace std ;
 7 queue < int > Q ;
 8 struct id
 9 {
10     int nxt , in ; bool vis ;
11 } node[maxn] ;
12 int n , ans = 0 ;
13 
14 inline void Init( )
15 {
16     freopen( "message.in" , "r" , stdin ) ;
17     freopen( "message.out" , "w" , stdout ) ;
18 }
19 
20 int read( )
21 {
22     char ch = getchar( ) ; int k = 1 , ret = 0 ;
23     while( ch < 0 || ch > 9 ) { if( ch == - )k = -1 ; ch = getchar( ) ; }
24     while( ch >= 0 && ch <= 9 ) ret = ret * 10 + ch - 0 , ch = getchar( ) ;
25     return ret * k ;
26 }
27 
28 void input(  )
29 {
30     n  = read( ) ;
31     for( int x = 1 ; x <= n ; ++x )
32         node[x].nxt = read( ) , node[node[x].nxt].in++ ;    
33 }
34 
35 
36 void sov( )
37 {
38     for( int x = 1 ; x <= n ; ++x ) if( !node[x].in ) { Q.push( x ) ; node[x].vis = true ; }
39     while( !Q.empty( ) )
40     {
41         int u = Q.front( ) ; Q.pop( ) ;    
42         int v = node[u].nxt ;
43         if( --node[v].in == 0 ) { Q.push( v ) ; node[v].vis = true ; }
44     } ans = inf ; 
45     for( int x = 1 ; x <= n ; ++x )
46     {
47         int cnt = 1 , j = node[x].nxt ; 
48         if( !node[x].vis )
49         {
50             while( j != x )
51             {
52                 cnt++ ;
53                 node[j].vis = true ;
54                 j = node[j].nxt ;
55             }
56             ans = min( ans , cnt ) ;
57         }
58         
59     }
60     printf( "%d\n" , ans ) ;
61 }
62 
63 
64 int main( )
65 {    
66     Init( ) ; 
67     input(  ) ;
68     sov( ) ;
69     fclose( stdin ) ;
70     fclose( stdout ) ;
71     return 0 ;
72 }

 

以上是关于noip 2015 提高组的主要内容,如果未能解决你的问题,请参考以下文章

如何评价NOIP2015提高组复赛试题

如何评价NOIP2015提高组复赛试题

JZYZOJ1452 NOIP2015_提高组Day2_1_跳石头

[NOIP2015 提高组] 运输计划

如何评价NOIP2015提高组复赛试题

noip2015提高组