回 帖 发 新 帖 刷新版面

主题:[原创][讨论][交流]编程高手的超级训练题解析

[code]
        [[color=FF0000]注意: 这儿绝大部分的题目来源于信息学竞赛!
        这些题目都是非常好的!如果大家能把这些题目做出来,那么可以说你
        的编程能力达到了一定的水平!
        关于这些题目的答案在GOOGLE/BAIDU上都能搜出来,但我:希望大家积极参 与讨论, 如果你把当中的题目做出来了可以贴出来,不过最好是要讲清自己的解题思路!
我也会把自己做出来了的题目以及解题思路发上来和大家一起交流!
         如果你想学好编程,那么实践是很重要的!
         我也是一个编程爱好者![/color]     
  [color=FF00FF]            My dream is to
       develop a better than Linux, Windows more popular than the OS! [/color]        
          有啥问题,可以联系本人: 见我的签名档!
         ]
         
 第二届全国青少年信息学(计算机)奥林匹克分区联赛复赛试题 
             (高中组  竞赛用时:3小时)
             [color=FF00FF] 编号为: gcc_1[/color] 
[/code]
[quote]


1.比赛安排(20分)
    设有有2 n(n<=6)个球队进行单循环比赛,计划在2 n ? 1天内完成,每个队每天进行一场比赛。设计一个比赛的安排,使在2 n ? 1天内每个队都与不同的对手比赛。
例如n=2时的比赛安排:
    队         1  2            3  4
    比赛       1==2            3==4             一天
               1==3            2==4             二天
               1==4          2==3             三天





2.数制转换(20分)
    设有一个字符串A$的结构为:  A$=’m<n>p’
    其中m为数字串(长度<=20),而n,p均为1或2位的数字串(其中所表达的内容在2-10之间)。
    程序要求:从键盘上读入A$后(不用正确性检查),将A$中的数字串m(n进制),以p进制的形式输出。
    例如:A$=’48<10>8’
          其意义为:将10进制数48,转换成8进制数输出。
          输出结果为:48<10>=60<8>




3.挖地雷(30分)
    在一个地图上有N个地窖(N<=20),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。


V1               V 2             V3                       V4                         V5  

例如:
[题目要求]
当地窖及其连接的数据给出之后,某人可以从任一处开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。
    输入格式: N:                       (表示地窖的个数)
            W1,W2,W3,……WN     (表示每个地窖中埋藏的地雷数量)
                    A12…………… .     A1N      
                        A23…………..A2N        
                        ……..
                               AN-1  N
    
    输出格式:
      K1--K2--……….KV                  (挖地雷的顺序)
      MAX                            (挖地雷的数量)
例如:

       ⑩--------⑧    ④-----⑦-------⑥

其输入格式为:                   输出:
               5                        1  ?3  -4  -5
10,8,4,7,6            max=27
    1  1  1  0
       0  0  0
          1  1 
             1
 



4.砝码称重(30分)
设有1g、2g、3g、5g、10g、20g的砝码各若干枚(其总重<=1000),
要求:
    输入方式:a1  a2  a3  a4  a5  a6
             (表示1g砝码有a1个,2g砝码有a2个,…,20g砝码有a6个)
    输出方式:Total=N
             (N表示用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况)
如输入:1_1_0_0_0_0   (注:下划线表示空格)
  输出:TOTAL=3  表示可以称出1g,2g,3g三种不同的重量。


[/quote]

  

回复列表 (共83个回复)

51 楼

[code]
续...............
int do_10_to_other (int b[], int s[], int p ,int lb)
    {
        int c[MAX] ;
        int i,j,k,mod ;
        int ls = 0, lc = 0 ;
        while ( (lb >1) || (lb == 1 && b[1] > 0 ) )
        {
            memset(c , 0 , sizeof(c) );
            lc = 0 ;
            
            for(i= lb ; i>=1 ;i-- )
            {
                if( b[i] < p)
                {
                    if ( lc >= 1)
                    {
                        c[++lc] = b[i] / p ;
                    
                    }
                    
                    if ( i > 1)
                    b[i-1] += b[i] * 10 ;
                    
                    else 
                    mod = b[i] % p ;
                }
                else
                {
                c[++lc] = b[i] / p ;
                mod = b[i] % p ;
                if( i> 1)
                b[i-1] += mod * 10 ;
                
                }
            }
            s[++ls] = mod ;
            
            for(j= 1 ,k= lc ; j<=lc ; j++,k--)
            b[k] = c[j] ;
            lb = lc ;
        }            
    
        return ls ;
    }        
    
            
    int main(int argc, char *argv[])
    {
        int a[MAX]={0} ,s[MAX]={0} , b[MAX],st[MAX] ;
        int la=0 , ls = 0 , lb = 0  ;
        int i,j,k ;
        int m,n,p ;
        char c1,c2 ;
        while ( (c1=getchar())!= '<') //&& c1 >= '0' && c1 <= '9')
        {
            if( c1 >= '0' && c1 <= '9' )
            st[++la] = (int) (c1-'0') ;
        }
        scanf("%d", &n) ;
        c1 = getchar() ;
        scanf("%d", &p ) ;
        
        for(i=1 , j= la ; j>=1 ; j--, i++)
        a[j] = st[i] ;
        
        if( n != 10 && p != 10 )
        {
            lb = change_to_10 ( a, b , n , la ) ;
            
            ls = do_10_to_other(b, s , p ,lb ) ;
        
        }
        else if( n!= 10 && p == 10 )
        {
            ls = change_to_10 ( a , s, n , la ) ;
        }
        else if( n == 10 && p != 10 )
        {
            ls = do_10_to_other(a,s, p ,la) ;
        }
        else
        {
            //memory (&s[1], &a[1] , sizeof(int)* la ) ;
            for(i=1 ; i<= la ; i++)
            s[i] = a[i] ;
            ls = la ;
        }
        
        for( i= ls ; i>=1 ; i--)
        printf("%d ", s[i] );
        
        
        /*#if need
        for(i=1 ; i<=la ; i++)
        printf("%d ",a[i]) ;
        printf("%d %d",n, p );
        #endif*/
        return 0 ;
    }
            
    
[/code]

52 楼

[quote]



学习计划:

一. 基础知识巩固
    1. 数据结构
    
    (1)数组,高级数组(树状数组)
    
    (2)动态分配(指针的高级应用)
    
    (3)链表,高级链表
    
    (4)栈,顺序栈与链栈(表达式计算)
    
    (5)队列,优先队列
    
    (6)字符串操作,串匹配(KMP算法)
    
    (7)树的高级应用(二叉树,平衡树,线段树等),表达式求值
    
    (8)图的经典算法(DFS,BFS,MST,最短路径等), (prim,Djiskatra,kual)
    
    (9)网络: 网络流,图的连通性问题,最小费用流,最大流等问题
    
    (10)各种数据结构的综合应用
    
    
    2.算法设计与分析
    
    (1)递归与分治( 二分法,大数运算等)
    
    (2)搜索算法(DFS,BFS,穷举法,回溯法,分枝限界法,以各种搜索算法的巧妙结合算法等)
    
    (3)贪心算法(要学习证明,识别贪心选择性的正确与否)
    
    (4)动态规划 (此法必须熟能生巧,知道什么样的问题可以用DP去解)(掌握滚动数组与DP 的 巧妙 应用)
    
    (5)网络流算法(此法也必须撑握)
    
    (6)线性规划
    

    
二.读经典书.
    1. <<算法艺术与信息学竞赛>>
    
    2.<<The art of compute program>>
    
    3.<<编译原理>>
    
    4.<<编程艺术>>
    
    5.<<孙子兵法>>
    
    6.<<数论>>
    
    7.<<计算机组合学>>
    
    8.<<程序调试技巧>>
    
    9.<<算法设计与分析实验题解>>
    
三.系统全面地强化训练
    
    1.系统强化数据结构(全部用代码实现)
    
    2.语言技巧(充分利用C语言本身的优点,例如: 位运算, 指针等 去写出技术含量高的代码) 以及 (C语言的熟能生巧)
    
    3.各种算法的经典运用,全部用代码去实现!
    
    4.熟练各种算法 (算法设计与分析题解以及其它网上的有关资料)
    
    5.针对各种问题的解决方法(做网上的题库,VIJOS,FLYIOI,以及其它OJ )
    
四.培养编程的感觉,和良好的考试心态

    1.每周模拟训练: (时间:3小时 ; 题目: 历届竞赛题 或 其它省的选拔试题 )
    
    2.学会怎样去发挥
    
    3.培养考试的能力,创作出自己的一种做题技巧
    
    4.每次训练后的小结
    
    5.树立信心,力争400分

五.总结

    1.总结平时的学习经验,吸取教训,从而避免在竞赛时出错
    
    2.复习以前的学习笔记
    
    3.复习C语言的各方面的知识(语法,注意事项等)
    
    4.以一平常心去对待竞赛
    
    5.考试技巧

[/quote]

53 楼

读经典书.
    1. <<算法艺术与信息学竞赛>>
    
    2.<<The art of compute program>>
    
    3.<<编译原理>>
    
    4.<<编程艺术>>
    
    5.<<孙子兵法>>
    
    6.<<数论>>
    
    7.<<计算机组合学>>
    
    8.<<程序调试技巧>>
    
    9.<<算法设计与分析实验题解>>

楼上的有上面列出的电子书吗?

54 楼

[quote]读经典书.
    1. <<算法艺术与信息学竞赛>>
    
    2.<<The art of compute program>>
    
    3.<<编译原理>>
    
    4.<<编程艺术>>
    
    5.<<孙子兵法>>
    
    6.<<数论>>
    
    7.<<计算机组合学>>
    
    8.<<程序调试技巧>>
    
    9.<<算法设计与分析实验题解>>

楼上的有上面列出的电子书吗?[/quote]

[code]
只有第九本没有,其它的都有!
你也要吗?
[/code]

55 楼

[code]

[color=FF00FF]
GCC-6-1 的解答:
主要有两种方法:
[/color]
/* * *    =======name : gcc-6-1.c==========* * *
     
        Input : 2 
        output:    1 2 
            4 3
     * * *  =================================* * */
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <memory.h>
    #include <time.h>
        
    #define MAX     11
    #define true    1
    #define false    0
    #define INF 10001
    
    int f[MAX*MAX+1],flag = 0 ;
    
    int N ,total = 0 ;
    int chose = 0 , save = INF ;
    
    int a[MAX][MAX],s[MAX][MAX] ;
    
    int pr[INF], lp = 0 ;
    
    void output ()
    {
        int i,j,sum=0 ;
        
        //printf("\n========The %d kind way !=========\n",total) ;
        
        
        sum += a[1][1] ;
        
        for(i= 2 ; i<= N ; i++)
        sum += a[1][i]+ a[i][1] ;
        
        if ( sum < save)
        {
            save = sum ;
            chose = total ;
            for(i=1 ; i<=N ; i++)
            for(j=1 ; j<=N ; j++)
            s[i][j] = a[i][j] ;
            
        }
        
        /*for(i=1 ; i<= N ; i++)
        {
            for(j=1 ; j<=N ; j++)
            printf("%d\t",a[i][j]) ;
            printf("\n\n") ;
        }
        
        printf("\n") ;*/
            
    }

    void prime ()
        {
                int r,t,v ;
                int h[INF] ;

                v = 2 * N * N;

                h[1] = false ;

                for( r = 2 ; r <=v ; r++)
                h[r] = true ;

                for( t = 2 ; t <= v ; t++)
                {
                        if( h[t] )
                        {
                                for(r = t+t;r <= v ; r+= t)
                                h[r] = false ;
                        }
                }

                for( t= 2 ; t<= v ; t++)
                if(h[t])
                pr[++lp] = t ;

        }

    
    [/code]

56 楼

[code]
int is_prime( int num )
    {
        int k ;
        for(k=1 ; k<=lp ; k++)
        if(num == pr[k])
        return true ;
        
        return false ;
    }        


    /*int is_prime ( int num ) /if a prime or not *
    {
        register int k ;
        
        if(num <= 1 )
        return false ;
        
        if(num == 2 )
        return true ;
        
        for(k = 2 ; k*k <= num ; k++)
        if( num % k == 0)
        return false ;
        
        return true ;
    }*/
     
    
    int is_ok ( int x, int y ,int data) /* check the legal */
    {
        if( x== 1 && is_prime(data + a[x][y-1]) )
        return true ;
        
        if( y== 1 && is_prime(data + a[x-1][y]) ) 
        return true ;
        
        if( x > 1 && y > 1  && is_prime(data+a[x][y-1]) && is_prime(data + a[x-1][y] ) )
        return true ;
        
        return false ;
    }
    
    [/code]

57 楼

[code]
 void try_do (int x, int y , int n )
    {
        
        int i,j,k ;
        
        
        if ( n == N * N )
        {    
            total ++ ;
            
            output() ;
            flag = 1 ;
            
            //return 1 ;
            
            
        }
        
        else
        {
            if ( y == N +1 )
            {
                y = 1 ;
                x = x + 1 ;
            }
            
            for(i = 2 ; i<= N*N ; i++)
            if( !f[i] && is_ok(x,y,i) )
            {
                if(total >10)
                break ;
                f[i] = true ;
                a[x][y] = i ;
                
                try_do(x , y+1 , n+1 ) ;
                
                f[i] = false ;
                a[x][y] = 0  ;
            }
            
        }
        
        /*if( flag )
        return 1 ;
        
        else
        return 0 ;*/
    
    
    }
            
                
    int main(int argc, char *argv[])
    {
        int ans,p,q;
        clock_t begin, end ;
        
        scanf("%d",&N) ;
        
        begin = clock() ;
        
        memset(a, 0 , sizeof(a) ) ;
        memset(f, 0 , sizeof(f) ) ;
        memset(s, 0 , sizeof(s) ) ;
        memset(pr, 0 , sizeof(pr) ) ;
        
        prime() ;
        
        a[1][1] = 1 ;
        f[1] = 1 ;
        
        try_do (1, 2 , 1 ) ;
        
        if( flag == 0 )
        
        printf("NO ANSERS!\n") ;
        else
        {
            printf("\nThe best kind way is %d and his sum is %d \n",chose, save ) ;
            for(p= 1 ; p<= N ; p++)
            {
                for(q= 1;q<= N ; q++)
                printf("%d\t",s[p][q]);
                printf("\n");
            }
        }
        
        end = clock() ;
            
        printf("\nTo compute of the num of %d should cost %f seconds!\n",N, (double)(end-begin)/1000 ) ;
        
        return 0 ;
    }    
[/code]

58 楼

[code]

第二种方法:

/* * *    =======name : gcc-6-1.c==========* * *
     
        Input : 2 
        output:    1 2 
            4 3
     * * *  =================================* * */
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <memory.h>
    #include <time.h>
        
    #define MAX     11
    #define true    1
    #define false    0
    #define INF 1001
    
    
    int f[MAX*MAX+1],flag = 0 ;
    
    int N ,total = 0 ;
    
    
    int a[MAX][MAX] ;
    
    int pr[INF], lp = 0 ;
    
    void prime ()
        {
                int r,t,v ;
                int h[INF] ;

                v = 2 * N * N;

                h[1] = false ;

                for( r = 2 ; r <=v ; r++)
                h[r] = true ;

                for( t = 2 ; t <= v ; t++)
                {
                        if( h[t] )
                        {
                                for(r = t+t;r <= v ; r+= t)
                                h[r] = false ;
                        }
                }

                for( t= 2 ; t<= v ; t++)
                if(h[t])
                pr[++lp] = t ;

        }

    
    int is_prime( int num )
    {
        int k ;
        for(k=1 ; k<=lp ; k++)
        if(num == pr[k])
        return true ;
        
        return false ;
    }        


        
    int is_ok ( int x, int y ,int data) /* check the legal */
    {
        if( x== 1 && is_prime(data + a[x][y-1]) )
        return true ;
        
        if( y== 1 && is_prime(data + a[x-1][y]) ) 
        return true ;
        
        if( x > 1 && y > 1  && is_prime(data+a[x][y-1]) && is_prime(data + a[x-1][y] ) )
        return true ;
        
        return false ;
    }
    
    [/code]

59 楼

[code]
void try_do (int x, int y , int n )
    {
        
        int i,j,k ;
        
        
        if ( n == N * N )
        {    
        
            flag = 1 ;
            
        }
        
        else
        {
            if ( y == N +1 && x == 1)
            {
                y = 1 ;
                x = x + 1 ;
            }
            else if( x == N+1 )
            {
                y = y+1 ;
                x = 2 ;
            }
            
            for(i = 2 ; i<= N*N ; i++)
            if( !f[i] && is_ok(x,y,i) )
            {
                if( flag == 1 )
                break ;
                
                f[i] = true ;
                a[x][y] = i ;
                
                if( x == 1)
                try_do(x , y+1 , n+1 ) ;
                else
                try_do(x+1,y ,n+1) ;
                
                if( flag == 1)
                break ;
                f[i] = false ;
                a[x][y] = 0  ;
            }
            
        }
        
            
    }
            
    int main(int argc, char *argv[])
    {
        int ans,p,q;
        clock_t begin, end ;
        
        scanf("%d",&N) ;
        
        begin = clock() ;
        
        memset(a, 0 , sizeof(a) ) ;
        memset(f, 0 , sizeof(f) ) ;
        
        prime() ;
        
        a[1][1] = 1 ;
        f[1] = 1 ;
        
        try_do (1, 2 , 1 ) ;
        
        if( flag == 0 )
        
        printf("NO ANSERS!\n") ;
        
        else
        {
            printf("\n=======The best kind way is=============\n") ;
            for(p= 1 ; p<= N ; p++)
            {
                for(q= 1;q<= N ; q++)
                printf("%d\t",a[p][q]);
                printf("\n");
            }
        }
        
        end = clock() ;
            
        printf("\nTo compute of the num of %d should cost %f seconds!\n",N, (double)(end-begin)/1000 ) ;
        
        return 0 ;
    }    
[/code]

60 楼

[quote]

[color=FF00FF]
测试结果如下:
[/color]

[root@localhost gcc-6]# ./gc6-1
5

=======The best kind way is=============
1       2       3       4       7
6       5       14      15      16
13      24      23      8       21
10      19      18      11      20
9       22      25      12      17

To compute of the num of 5 should cost 0.000000 seconds!
[root@localhost gcc-6]# ./gc6-1
1

=======The best kind way is=============
1

To compute of the num of 1 should cost 0.000000 seconds!
[root@localhost gcc-6]# ./gc6-1
2

=======The best kind way is=============
1       2
4       3

To compute of the num of 2 should cost 0.000000 seconds!
[root@localhost gcc-6]# ./gc6-1
4

=======The best kind way is=============
1       2       11      12
4       9       8       5
7       10      3       14
6       13      16      15

To compute of the num of 4 should cost 0.000000 seconds!
[root@localhost gcc-6]# ./gcc-6-1
4

The best kind way is 1 and his sum is 43
1       2       11      12
4       9       8       5
7       10      3       14
6       13      16      15

To compute of the num of 4 should cost 10.000000 seconds!

[/quote]

我来回复

您尚未登录,请登录后再回复。点此登录或注册