第二届“传智杯”全国大学生IT技能大赛(初赛)赛后总结
本次赛后总结写的很及时O(∩_∩)O哈哈~
P6363 软件工程实习
这道题想必很多同学都别坑了,我试错了5次才AC,挺简单的一道题,没有什么复杂的算法,就很基本的按照题意一步一步走就行,但是坑却不少,首先是数据类型的选择,其次的四舍五入,第一次算均值是不需要四舍五入的,第二次才需要;四舍五入可以直接用round()函数。这些做到后还是不行的,因为最后求总分的时候需要四舍五入,所以记录分数的类型也需要是double才行,就是因为这一点没做到,试错了1个小时,被第一题难倒真的是心态爆炸啊!
using namespace std;
#include<bits/stdc++.h>
struct node{
double score;
char team;
};
bool cmp(node a,node b){
if(a.score == b.score) return a.team<b.team;
else return a.score>b.score;
}
int main(){
int n,k;
node s[1005];
int tm[30][30];
bool flag[30][30]={0};
int i,j;
cin>>n>>k;
for(i=1;i<=n;i++) cin>>s[i].score>>s[i].team;
for(i=1;i<=k;i++)
{
for(j=1;j<=k;j++)
{
cin>>tm[i][j];
flag[i][j]=1;
}
}
double sum[30]={0};
for(i=1;i<=k;i++)
{
for(j=1;j<=k;j++)
{
sum[i]+=tm[j][i];
}
sum[i]/=k;
// sum[i]=round((double)sum[i]/k);
}
//test
// for(i=1;i<=k;i++) cout<<sum[i]<<'\n';
for(i=1;i<=k;i++)
{
for(j=1;j<=k;j++)
{
if(abs(tm[j][i]-sum[i])>15)
{
flag[j][i]=0;
}
}
}
for(i=1;i<=k;i++)
{
sum[i]=0;
int tmp=0;
for(j=1;j<=k;j++)
{
if(flag[j][i]==1)
{
sum[i]+=tm[j][i];
tmp++;
}
}
sum[i]=round((double)sum[i]/tmp);
}
//test
// for(i=1;i<=k;i++) cout<<sum[i]<<'\n';
for(i=1;i<=n;i++)
{
s[i].score=round(s[i].score*0.6+sum[s[i].team-'A'+1]*0.4);
}
sort(s+1,s+n+1,cmp);
for(i=1;i<=n;i++) cout<<s[i].score<<" "<<s[i].team<<"\n";
return 0;
}
P6364 1024 程序员节发橙子
第二题也听基本的,初看可能会觉得挺复杂,但其实就是遍历,因为做的时候临界条件想复杂了所有最后一个案例超时了只拿了80,顺带吐槽下传智杯的排名方式,不是按分数来的,必须是AC了才算,赛后看了下官方在知乎的题解,又问了下同学才知道临界条件其实只要设个flag就可以了。
下附赛后测试地址:
https://www.dotcpp.com/oj/problemset.php?search=%E4%BC%A0%E6%99%BA%E6%9D%AF
超时代码:
using namespace std;
#include<bits/stdc++.h>
const int MAX=1e6+5;
int score[MAX];
int org[MAX];
int n;
bool isok(){
for(int i=1;i<n;i++)
{
if(score[i]<score[i+1] && org[i]>=org[i+1]) return false;
else if(score[i]>score[i+1] && org[i]<=org[i+1]) return false;
else if(score[i]==score[i+1] && org[i]!=org[i+1]) return false;
}
return true;
}
int main(){
int i;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&score[i]);
org[i]=1;
}
while(!isok())
{
for(i=1;i<n;i++)
{
if((score[i]<score[i+1] && org[i]<org[i+1]) || (score[i]>score[i+1] && org[i]>org[i+1]) || (score[i]==score[i+1] && org[i]==org[i+1])) continue;
else if(score[i]<score[i+1] && org[i]>=org[i+1]) org[i+1]++;
else if(score[i]>score[i+1] && org[i]<=org[i+1]) org[i]++;
else if(score[i]==score[i+1] && org[i]<org[i+1]) org[i]=org[i+1];
else if(score[i]==score[i+1] && org[i]>org[i+1]) org[i+1]=org[i];
}
}
long long sum=0;
for(i=1;i<=n;i++)
{
sum+=org[i];
// cout<<org[i]<<" ";
}
printf("%lld",sum);
return 0;
}
AC代码:
using namespace std;
#include<bits/stdc++.h>
const int MAX=1e6+5;
int score[MAX];
int org[MAX];
int n;
int main(){
int i;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&score[i]);
org[i]=1;
}
bool flag=true;
while(flag)
{
flag=false;
for(i=1;i<n;i++)
{
if((score[i]<score[i+1] && org[i]<org[i+1]) || (score[i]>score[i+1] && org[i]>org[i+1]) || (score[i]==score[i+1] && org[i]==org[i+1]))
{
continue;
}
else if(score[i]<score[i+1] && org[i]>=org[i+1])
{
org[i+1]=org[i]+1;
flag=true;
}
else if(score[i]>score[i+1] && org[i]<=org[i+1])
{
org[i]=org[i+1]+1;
flag=true;
}
else if(score[i]==score[i+1] && org[i]<org[i+1])
{
org[i]=org[i+1];
flag=true;
}
else if(score[i]==score[i+1] && org[i]>org[i+1])
{
org[i+1]=org[i];
flag=true;
}
}
}
long long sum=0;
for(i=1;i<=n;i++)
{
sum+=org[i];
// cout<<org[i]<<" ";
}
printf("%lld",sum);
return 0;
}
P6365 众数出现的次数
第三题做起来就比较坎坷了,最初的想法是直接开一个1e9大小的数组然后分别将红、黑和异或后的结果直接加进去,然后直接一次遍历找到最大值就行,后来发现即使是全局变量,在堆里面,也是开不了1e9这么大的数组的。
于是转变方案,直接一个sum数组记录记录下所有的数然后sort排序,在一次遍历找到最多的数,但是这样提交后也只过了第一个案例,仔细看了一遍题目,才发现,每个人有3个数,但是每个人只能选一个数出,也就是如果一个人有2个数是相同的话那么只能算一次,所以又完善方案定义了结构体来记录每个数对应的team,再排序计数,原以为没问题了,但没想到最后只过了2个案例,才32分。一直到7点我都没想明白问题出在哪里,最后只好放弃,o(╥﹏╥)o
赛后看完了题解觉着自己的思路和他一样的啊,也不知道问题出在那里,如果哪位大佬能看到这篇文章,找到了代码中的问题,烦请评论区留言,提前谢谢大佬!
未能AC的代码:
using namespace std;
#include<bits/stdc++.h>
const int MAX=1e6+5;
const int MAX2=1e7;
int r[MAX],b[MAX],s[MAX];
struct node{
int a;
int team;
}sum[MAX2];
bool cmp(node x,node y){
if(x.a == y.a) return x.team<y.team;
else return x.a<y.a;
}
int main(){
int n,i;
cin>>n;
int num=0;
for(i=1;i<=n;i++)
{
cin>>r[i]>>b[i];
s[i]=r[i]^b[i];
sum[num].a=r[i];
sum[num++].team=i;
sum[num].a=b[i];
sum[num++].team=i;
sum[num].a=s[i];
sum[num++].team=i;
}
// for(i=1;i<=n;i++) cout<<r[i]<<" "<<b[i]<<" "<<s[i]<<"\n";
sort(sum,sum+num,cmp);
// for(i=0;i<num;i++) cout<<sum[i].a<<" "<<sum[i].team<<"\n";
int m1=0,m2=0,index=0;
for(i=0;i<num;i++)
{
m1=1;
while(sum[i].a == sum[i+1].a && sum[i].team != sum[i+1].team)
{
m1++;
i++;
if(i == num-1) break;
}
if(m1>m2)
{
m2=m1;
index=sum[i].a;
}
}
cout<<index;
return 0;
}
附上整个赛题的提交记录:
同上次蓝桥杯模拟,最后一题一来已经被前几题虐的很惨了,二来最后一题确实没什么思路当时,所以就直接放弃没有做了。
总结一下,这次传智杯初赛,总共花了2个半小时,比上次蓝桥杯模拟有进步,赛题上,第一题100,第二题80,第三题32,第四题放弃,还是要继续加油呀!
非常感谢能看到最后的你,特别喜欢C语言网的这份公告
混一天和努力一天,一天看不出来任何差别,三天看不到任何变化,七天也看不到任何距离,但是一个月后会看到话题不同,三个月后会看到气场不同,半年后会看到距离不同,一年后会看到人生道路截然不同。
送给每个仍在为梦想努力奋斗的你!