浙大复试上机题目解答(2)

本文提供了ACM竞赛中经典问题的解答,包括寻找最小公路总长度、统计同成绩学生人数等,采用C++语言实现算法,适合算法初学者和ACM爱好者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 浙大复式上机题目解答(2)

 贴在一起太长了,还是分开贴吧。。

第六题:

还是畅通工程

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 532    Accepted Submission(s): 247


Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
 


Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
 


Output
对每个测试用例,在1行里输出最小的公路总长度。
 


Sample Input
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
 


Sample Output
3
5

#include <iostream>
#include 
<cstring>
using namespace std;
int matrix[128][128];
int nearest[128];
int flag[128],n;
void Init()
{
    memset(matrix,
0,sizeof(matrix));
    memset(nearest,
0,sizeof(nearest));
    memset(flag,
0,sizeof(flag));
}

int findmin(int * arr)
{
  
int i;
  
int min=111111111,p;
  
for(i=1;i<=n;i++)
   
if(!flag[i])
     
{
            
if(arr[i]<min)
             
{
                    min
=arr[i];
                    p
=i;
             }

        }

   
return p;      
}

int main()
{
    
int i,j;
    
int sum;
    
while(1)
    
{
         scanf(
"%d",&n);
         
if(!n)break;
         Init();
         sum
=0;
         
int a,b,v,min=1000000000,p;
         
for(i=0;i<n*(n-1)/2;i++)
          
{
                scanf(
"%d%d%d",&a,&b,&v);
                matrix[a][b]
=v;
                matrix[b][a]
=v;
                
if(v<min)
                 
{
                        min
=v;p=a;
                 }

          }

          flag[p]
=1;
          
for(i=1;i<=n;i++)
          
{
           nearest[i]
=matrix[p][i];
          }

          
for(i=2;i<=n;i++)
           
{
                p
=findmin(nearest);
                flag[p]
=1;
                sum
+=nearest[p];
                
for(j=1;j<=n;j++)
                 
if(!flag[j])
                   
{
                        
if(matrix[p][j]<nearest[j])
                         nearest[j]
=matrix[p][j];
                    }

            }
    
        cout
<<sum<<endl;
    }

    
return 0;
}

第七题:

开门人和关门人

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 353    Accepted Submission(s): 207


Problem Description
每天第一个到机房的人要把门打开,最后一个离开的人要把门关好。现有一堆杂乱的机房签
到、签离记录,请根据记录找出当天开门和关门的人。
 


Input
测试输入的第一行给出记录的总天数N ( > 0 )。下面列出了N天的记录。
每天的记录在第一行给出记录的条目数M ( > 0 ),下面是M行,每行的格式为

证件号码 签到时间 签离时间

其中时间按“小时:分钟:秒钟”(各占2位)给出,证件号码是长度不超过15的字符串。
 Output
对每一天的记录输出1行,即当天开门和关门人的证件号码,中间用1空格分隔。
注意:在裁判的标准测试输入中,所有记录保证完整,每个人的签到时间在签离时间之前,
且没有多人同时签到或者签离的情况。
 Sample Input
3
1
ME3021112225321 00:00:00 23:59:59
2
EE301218 08:05:35 20:56:35
MA301134 12:35:45 21:40:42
3
CS301111 15:30:28 17:00:10
SC3021234 08:00:00 11:25:25
CS301133 21:45:00 21:58:40
 Sample Output
ME3021112225321 ME3021112225321
EE301218 MA301134
SC3021234 CS301133
#include <iostream>
#include 
<string>
#include 
<cstdio>
using namespace std;
int days,m;
int strToint(string str)
{
   
int seconds;
   
int minutes;
   
int hours;
   seconds
=str[7]-'0'+(str[6]-'0')*10;
   minutes
= str[4]-'0'+(str[3]-'0')*10;   
   hours
=str[1]-'0'+(str[0]-'0')*10;
   
return hours*3600+minutes*60+seconds;
}

int main()
{
    scanf(
"%d",&days);
    
    
string minstr,maxstr,tmp,times1,times2;
    
while(days--)
    
{
        
int min=1000000000,max=-1,now1,now2;
        scanf(
"%d",&m);
        
while(m--)
        
{
              cin
>>tmp;
              cin
>>times1>>times2;
              now1
=strToint(times1);
              now2
=strToint(times2);
              
if(now1<min){minstr=tmp;min=now1;}
              
if(now2>max){maxstr=tmp;max=now2;}
              
        }

        cout
<<minstr<<" "<<maxstr<<endl;
    }

    
    
return 0;
}

第八题:

统计同成绩学生人数

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 857    Accepted Submission(s): 433


Problem Description
读入N名学生的成绩,将获得某一给定分数的学生人数输出。
 

Input
测试输入包含若干测试用例,每个测试用例的格式为


第1行:N
第2行:N名学生的成绩,相邻两数字用一个空格间隔。
第3行:给定分数

当读到N=0时输入结束。其中N不超过1000,成绩分数为(包含)0到100之间的一个整数。
 

Output
对每个测试用例,将获得给定分数的学生人数输出。
 

Sample Input
3
80 60 90
60
2
85 66
0
5
60 75 90 55 75
75
0
 

Sample Output
1
0
2

#include <iostream>
#include 
<cstdio>
#include 
<cstring>
using namespace std;
int grade[128];
bool Input()
{
    
int n,i;
    scanf(
"%d",&n);
    
    
if(!n)return false;
    memset(grade,
0,sizeof(grade));
    
int tmp;
     
for(i=0;i<n;i++)
     
{ scanf("%d",&tmp);
       grade[tmp]
++;
      }
    
    scanf(
"%d",&tmp);
    cout
<<grade[tmp]<<endl;
    
}

int main()
{
    
while(Input());
    
    
return 0;
}

第九题:

排名

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 628    Accepted Submission(s): 194


Problem Description
今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑
每题的分值,所以并不是最后的排名。给定录取分数线,请你写程序找出最后通过分数线的
考生,并将他们的成绩按降序打印。
 


Input
测试输入包含若干场考试的信息。每场考试信息的第1行给出考生人数N ( 0 < N
< 1000 )、考题数M ( 0 < M < = 10 )、分数线(正整数)G;第2行排序给出第1题至第M题的正整数分值;以下N行,每行给出一
名考生的准考证号(长度不超过20的字符串)、该生解决的题目总数m、以及这m道题的题号
(题目号由1到M)。
当读入的考生人数为0时,输入结束,该场考试不予处理。
 


Output
对每场考试,首先在第1行输出不低于分数线的考生人数n,随后n行按分数从高
到低输出上线考生的考号与分数,其间用1空格分隔。若有多名考生分数相同,则按他们考
号的升序输出。
 


Sample Input
4 5 25
10 10 12 13 15
CS004 3 5 1 3
CS003 5 2 4 1 3 5
CS002 2 1 2
CS001 3 2 3 5
1 2 40
10 30
CS001 1 2
2 3 20
10 10 10
CS000000000000000001 0
CS000000000000000002 2 1 2
0
 


Sample Output
3
CS003 60
CS001 37
CS004 37
0
1
CS000000000000000002 20

#include <iostream>
#include 
<string>
#include 
<cstring>
#include 
<algorithm>
using namespace std;
class student
{
    
public:
        
char ID[32];
        
int grade;
        
bool operator <(student &B)
        
{
            
if(grade!=B.grade)
              
return grade<B.grade;
            
else return strcmp(ID,B.ID)>0?true:false
            
        }

    
}
;
student stu[
1024];
int stu_num,que_num,line;
int g[16];
bool Input()
{
    cin
>>stu_num;
    
if(!stu_num)return false;
    cin
>>que_num>>line;
    
int i,j;
    
int tmp,n,x,pass=0;
    
for(i=1;i<=que_num;i++)
      cin
>>g[i];
    
for(i=1;i<=stu_num;i++)
      
{
            cin
>>stu[i].ID;
            cin
>>n;
            tmp
=0;
            
for(j=0;j<n;j++)
            
{
                cin
>>x;
                tmp
+=g[x];
            }
  
            stu[i].grade
=tmp;
            
if(tmp>=line)pass++;
     }
  
    sort(stu
+1,stu+stu_num+1);
    cout
<<pass<<endl;
    
for(i=stu_num;i>=1;i--)
        
if(stu[i].grade>=line)
        
{
            cout
<<stu[i].ID <<" "<<stu[i].grade<<endl;
        }

        
    
return true;
}

int main()
{
   
while(Input()); 
    
return 0;
}
第十题:

简单计算器

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 520    Accepted Submission(s): 157


Problem Description
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
 

Input
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
 

Output
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
 

Sample Input
1 + 2
4 + 2 * 5 - 7 / 11
0
 

Sample Output
3.00
13.36
 
#include <iostream>
#include 
<vector>
#include 
<sstream>
using namespace std;
vector
<double> num;
vector
<char>  signal;
bool Solve()
{
    
string str;
    getline(cin,str);
     
if(str=="0")return false;//太阴险了吧, 
    istringstream in(str);
    num.clear();
    signal.clear();
   
double a,b;
    
in>>a;
    num.push_back(a);
    
char ch;
    
// cout.precision(2);cout.setf(ios::fixed);
  
    
while(in>>ch)
    
{
          
in>>b;
          
if(ch=='*')
               num[num.size()
-1]*=b;
           
else if(ch=='/')
               num[num.size()
-1]/=b;
           
else 
           
{
                num.push_back(b);
                signal.push_back(ch);
            }
 
           
                
    }

    
double ans=num[0];
   
int len=num.size();
   
for(int i=0;i<len-1;i++)
     
if(signal[i]=='-')
       ans
-=num[i+1];
      
else ans+=num[i+1];
    printf(
"%.2lf ",ans);  
    
//cout<<ans<<endl;
   return true
}

int main()
{
    
while(Solve());
    
return 0;
}

 我这就只有这些题目了,以后找到新的再贴上来。。。谁有其它的可以发上来哈
题目都很简单,不过很久没做acm的题目了,手生了,还是写了一个晚上才搞定。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值