回 帖 发 新 帖 刷新版面

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

[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个回复)

61 楼

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

=======The best kind way is=============
1       2       3       4       7       6       5       8       9       10
12      29      38      33      40      67      42      65      62      69
11      30      41      56      57      70      97      84      95      98
18      23      48      53      50      81      100     79      72      59
13      24      19      54      47      32      51      88      85      78
16      37      34      49      60      71      80      93      64      73
15      22      25      58      43      96      77      86      87      76
14      39      28      31      36      35      74      63      94      55
17      44      45      52      61      66      83      68      99      82
20      27      26      21      46      91      90      89      92      75

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


=======The best kind way is=============
1       2       3       4       7       6       5       8       9
10      21      38      75      52      61      42      65      74
13      40      63      64      37      46      55      48      23
16      27      34      19      24      43      54      53      56
15      26      45      22      49      30      59      44      57
14      33      28      25      78      71      68      69      80
17      20      39      58      73      66      35      62      47
12      41      32      51      76      31      36      77      60
11      18      29      50      81      70      67      72      79

To compute of the num of 9 should cost 69710.000000 seconds!
[root@localhost gcc-6]#
[/quote]

62 楼

[code]
我的程序无法在[color=FF00FF]1秒以内[/color]通过所有测试数据,哪位高手可以做到在
1秒以内通过1<=N<=10 这十个测试数据!
[color=FF00FF]
麻烦把程序贴出来,并说说你的解法!
-----------THANKS!
[/color]
[/code]

63 楼

[color=FF00FF]<gcc-24-3 :>麻烦各位帮我看一下,这个程序错在哪 ?
[/color]    
[code]
/* * * =========================* * *
        Input Sample:
            2 3 
            1 1 2 3 3 2
            1 2
            1 2 
    -------------    2 1 
            3 2 
            2 5
            2 4
        Output Sample:
            10
     * * * =========================* * */
        
    #include <stdio.h>
    
    #include <stdlib.h>
    
    #define MAX 21
    
    #define false     0
    #define true    1
        
    typedef struct node 
        {
            int fg;
            int med ;
            int tie ;
            int over;
        }Node ;
        
    struct save
        {
            Node sa[MAX] ;
        }op[MAX] ;
    
    struct time 
        {
            int begin ;
            int mid ;
            int end ;
        }time[MAX] ;
                
    
            
        int a[MAX] ;
        
        int flag[MAX] ;
        
        
        int m,n ;
        
        
        int main (int argc, char *argv[])
        {
            int i,j,k ;
            int su[MAX] ;
            int t1,t2,t3,t4,t5,fa ;
            int max_time = 0 ;
            
            memset( a, 0 ,sizeof(a) );
            memset( time,0 , sizeof(time) ) ;
            memset(op , 0 , sizeof(op) ) ;
            memset(flag , 0 , sizeof(flag) ) ;
            
            
            scanf("%d %d",&m, &n) ;
            
            for(i= 1 ; i<= m * n ;i++)
            scanf("%d",&a[i]) ;
                
            for(i= 1 ; i<= n; i++)
            {
                for(j=1 ; j<= m ; j++)
                scanf("%d",&op[i].sa[j].med) ;
            }
            
            for(i= 1 ; i<=n ; i++)
            {
                for(j=1 ; j<= m ; j++)
                scanf("%d",&op[i].sa[j].tie) ;
            }
            
            for(i= 1 ; i<= n ; i++)
            {
                for(j=1 ; j<=m ; j++)
                op[i].sa[j].fg = false ;
            }
            
            
            [/code]

64 楼

[code]

/* Beging to Compute */
            
            for(k = 1 ; k <= m*n ; k++ )
            
            //if ( flag[a[k]] == 0 || (op[a[k]].sa[flag[a[k]]-1].fg && 
            {
                flag[a[k]]++ ;
                op[a[k]].sa[flag[a[k]]].fg = true ;
                
                if(flag[a[k]]== 1 )
                {
                        t1 = time[op[a[k]].sa[1].med].begin ;
                        t2 = time[op[a[k]].sa[1].med].mid ;
                        t3 = time[op[a[k]].sa[1].med].end ;
                        t4 = op[a[k]].sa[1].tie ;
                        
                        if ( t2 - t1 > t4)
                        {
                            t1 += t4 ;
                            op[a[k]].sa[1].over = t1 ;
                            time[op[a[k]].sa[1].med].begin = t1 ;
                        }
                        
[/code]
                        

65 楼

[code]

else if ( t1 == t2 )
                        {
                            t3 += t4 ;
                            time[op[a[k]].sa[1].med].begin = t3 ;
                            time[op[a[k]].sa[1].med].mid = t3 ;
                            time[op[a[k]].sa[1].med].end = t3 ;
                            op[a[k]].sa[1].over = t3 ;
                        }
                        
                        else 
                        {
                            t3 += t4 ;
                            op[a[k]].sa[1].over = t3 ;
                            time[op[a[k]].sa[1].med].end = t3 ;
                        }
                }
                
                
       [/code]     
            
            
        

66 楼

[code]
else
      
                         {
                    fa = flag[a[k]] ;
                    
                    t1 = time[op[a[k]].sa[fa].med].begin ;
                    t2 = time[op[a[k]].sa[fa].med].mid ;
                    t3 = time[op[a[k]].sa[fa].med].end ;
                    t4 = op[a[k]].sa[fa].tie ;
                    t5 = op[a[k]].sa[fa-1].over ;
                    
                    if ( t1 >= t5 && t2-t1 >= t4)
                    {
                        t1 += t4 ;
                        op[a[k]].sa[fa].over = t1 ;
                        time[op[a[k]].sa[fa].med].begin = t1 ;
                    }
                    
                    else if( t3 >= t5 )
                    
                    {
                        t3 += t4 ;
                        op[a[k]].sa[fa].over = t3 ;
                        if( t2 - t1 == 0 )
                        {
                            time[op[a[k]].sa[fa].med].begin = t3 ;
                            time[op[a[k]].sa[fa].med].mid = t3 ;
                        }
                        
                        time[op[a[k]].sa[fa].med].end = t3 ;
                    }
else if ( t3 < t5 )
                    {
                        time[op[a[k]].sa[fa].med].mid = t3 ;
                        
                        t3 = t5 + t4 ;
                        
                        op[a[k]].sa[fa].over = t3 ;
                        time[op[a[k]].sa[fa].med].begin = t2 ;
                        time[op[a[k]].sa[fa].med].end = t3 ;
                    }
                        
                }
            }        
                        
                                            
            for(i=1 ; i<= m ; i++)
            if (time[i].end > max_time )
            max_time = time[i].end ;
                
            printf("\n ======the best time is %d =======\n",max_time ) ;                 
     
            
            return 0 ;
        }


            
[/code]        
                    

67 楼

[color=FF00FF]
gcc-24-3 参考答案: 终于被我AC了!
前面我写得那个程序太复杂了!
我现在换了一种技巧来"摸拟"!
用"0"来表示空闲时间, 用"1"来表示不可用时间!
虽然此时的时间复杂度为: O(m * n * max_time) !
但由于题目中的数据较小!
全0.0000sAC!
从总体分析!
[/color]

[code]
#include <stdio.h>
    
    #define MAX 21
    #define MAX_NUM 501
    
    struct node 
    {
        int time[MAX] ;
        int mede[MAX] ;
    
    }op[MAX] ; // op save the message of time and medicine
        
        
    int mt[MAX][MAX_NUM] ;// the medecine
    
    int m , n  ;
        
    int a[MAX*MAX+1] ; // the opeator order !
    
    int num[MAX] ;    // save the thing
    
    int save[MAX][MAX] ; //the save of the last time !
    
    int max_time = 0 ;
        
    int main(int argc, char *argv[])
    {
        
        int i, j , k , q , h ;
        int pa,pt,pk, t,t1,t2,t3,place ;
        
        /* Init the array  */
        memset ( save , 0 , sizeof(save) ) ;
        memset (num , 0 ,sizeof(num )  ) ;
        memset (a , 0 , sizeof(a) ) ;
        memset (op , 0 , sizeof(op) ) ;
        memset (mt , 0 , sizeof(mt) ) ;
        
        /* Output the message !*/
        
        scanf("%d %d",&m ,&n ) ;
        
        for(i= 1 ; i<= m*n ; i++)
        scanf("%d",&a[i]) ;
        
        for(i = 1; i<=n ; i++)
        for(j = 1; j<=m ; j++)
        scanf("%d",&op[i].mede[j]) ;
        
        for(i = 1; i<=n ; i++)
        for(j=1 ; j<= m ; j++)
        scanf("%d",&op[i].time[j]) ;
        
        /* Begin to  compute */
        
        for(k = 1 ; k<= m *n ; k++)
        {
            num[a[k]]++ ;
            pt = num[a[k]] ;
            
            pk = op[a[k]].mede[pt] ;
            
            t = op[a[k]].time[pt] ;
            place = 0 ;
            
            for( i= save[a[k]][pt-1]+1 ; ;i++ )
            {
                
                for(h = i ; h<= i+t-1; h++)
                if(mt[pk][h] == 1)
                break  ;
                
                if( h > i+t-1 )
                {
                    place = i ;
                    break ;
                }
            }
            
            
            for( j = place ; j<= place+t-1 ; j++)
            mt[pk][j] = 1 ;
            
            save[a[k]][pt] = place+t-1 ;
            
            
        }
                
        max_time = 0 ;    
                    
        for( i=1 ; i<= n ; i++ )
        if( save[i][m] > max_time )
        max_time = save[i][m] ;
            
        printf("%d\n",max_time ) ;
        
                        
                
        
        /*for(i=1; i<=n ; i++)
        {
            for(j=1; j<= m ; j++)
            printf("%d ", op[i].mede[j]) ;
            printf("\n") ;
        }*/
        
        return 0 ;
    }
    
    
[/code]

68 楼

 
[code]
[color=FF00FF]怎么啦!
[/color]
[color=FFF00]
PFAN最近好像不景气[/color][color=FF00FF]^--^[/color]

[/code]
 

69 楼

楼主可否把修改签名弄短点,看得有点辛苦.

70 楼

[quote]楼主可否把修改签名弄短点,看得有点辛苦.[/quote]
好的....

我来回复

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