2015GPNU新生赛题解

今年的题目结合了往年的题目和华工,华师新生赛题目,确实是历年最难。

* 1001 *

Problem Description

最近ACM协会各种各样的费用都要申报,会长一时忙到手慌脚乱。身为会员的我们,一定要想个办法帮他们解决这个问题。现在有n 个项目的费用要申报,且给定每个项目的费用,求出总共要申请的费用。

Input
输入数据有多组,每组数据的第一行是一个整数n(0<=n<=40)代表申报的项目数,第二行有n个实数,每个实数代表每一个项目的费用

Output
对于每组数据,输出一行,代表所有项目的总费用(结果保留两位小数)
Sample Input

5
1 2 3 4 5
3
4 5 6

Sample Output

15.00
15.00

* 这一题就没什么好说的了。 *

#include<stdio.h>
int main()
{//freopen ("1001input.txt", "r", stdin);//freopen ("1001output.txt", "w", stdout);int n,i;double s,a[40];while(scanf("%d",&n)!=EOF&&n>=0&&n<=40){for(i=0;i<n;i++)scanf("%lf",&a[i]);for(s=0,i=0;i<n;i++)s+=a[i];printf("%.2f\n",s);}return 0;
}

* 2 *

题目略。。

代码如下:

#include<stdio.h>
int main()
{//freopen ("1002input.txt", "r", stdin);//freopen ("1002output.txt", "w", stdout);int n,i,j;while(scanf("%d",&n)!=EOF&&n>0&&n<40&&n%2!=0){for(i=1;i<=n/2+1;i++){for(j=1;j<=(n-(2*i-1))/2;j++)printf(" ");for(j=1;j<=2*i-1;j++)printf("*");putchar('\n');}for(i=n/2;i>0;i--){for(j=1;j<=(n-(2*i-1))/2;j++)printf(" ");for(j=1;j<=2*i-1;j++)printf("*");putchar('\n');}}return 0;
}

* 3 *

Problem Description

经过激烈的考试,班上的考试成绩终于出来了,但是这些成绩不是排好序的,现在班主任希望能够得到一份按成绩排序的成绩单,你能帮忙把这些杂乱的成绩单整理好顺序吗?考试成绩包括四项:语文、数学、英语、理综。排名规则是按照四科的总分进行排序,对于总分成绩相等的同学,就按理综成绩排名,若理综成绩也相等,按学号输出)

Input
有多组测试实例,每个实例的第一行输入整数n(1<=n<=100),代表成绩单上的人数。
接下来的n行,每行输入四个数据,分别代表该同学的语文、数学、英语、理综成绩。(学生的学号默认从1到n。)

Output
排好名次的成绩单(学号+语文+数学+英语+理综)每次输出一组数据后要空一行。

Sample Input

4
90 100 110 220
110 120 75 215
80 85 75 200
120 120 120 260
3
93 36 122 203
69 21 115 231
88 81 25 13

Sample Output

4 120 120 120 260
1 90 100 110 220
2 110 120 75 215
3 80 85 75 200

1 93 36 122 203
2 69 21 115 231
3 88 81 25 13

这一题主要考察排序。大家可以使用冒泡法排序,这里用快排来排序。

#include<stdio.h>
#include<stdlib.h>#define MAX 1001struct student
{int num ;int chinese , math , English , lizong ;int sum ;
}stu[MAX] ;int cmp( const void * a , const void * b  )
{struct student * a1 = (struct student *)a ;struct student * b1 = (struct student *)b ;if( a1->sum != b1->sum ){return b1->sum - a1->sum ; //降序排}else{if( a1->lizong != b1->lizong ){return b1->lizong - a1->lizong  ; //降序排}elsereturn a1->num -  b1->num  ; //升序排}
}int main()
{int n ;while( scanf("%d",&n) != EOF ){for( int i = 0 ; i<n ; i++ ){scanf("%d %d %d %d",&stu[i].chinese , &stu[i].math , &stu[i].English , &stu[i].lizong ) ;stu[i].sum = stu[i].chinese + stu[i].math + stu[i].English + stu[i].lizong ;stu[i].num = i+1 ;}qsort( stu , n , sizeof(stu[0]) , cmp ) ;for( int i = 0 ; i<n ; i++ )printf("%d %d %d %d %d\n",stu[i].num , stu[i].chinese , stu[i].math , stu[i].English , stu[i].lizong ) ;printf("\n");}return 0;
}

* 1004 *

Problem Description

忙了一天,终于把kk的logo费弄到手了,小y有点累但非常开心,因为他的第一个赚钱项目完美完成了。有好心情肯定要刷微博,在刷微博的过程中,小y看到了一道“过河”的智力题。题目的内容如下:有n个人想过河,但只有一艘载重为M千克的船;虽然每个人的体重不会超过船的载重,但是,为了安全起见,每次最多只能2个人同时乘船过河。请你想出一个过河的方法,以尽可能少的次数帮助所有人都顺利过河,并回答最少需要多少次。看到这样的题目,小y很是兴奋,这摆明了是一道算法题嘛,他认为能做出这道题,这样,他离冠军就又靠近一步了。

Input
输入包括多组数据,第一行是一个正整数n ,然后n个正整数,接着一行输入M 。

0 < n <= 100 , 0 < weight[i] < M < 1000
Output
每组数据输出一行,包含一个整数
Sample Input

4
23 70 29 23
140

Sample Output

2

这里呢,主要运用了贪心法。每一次都尽可能保证运过去的人的重量是最多的,即可。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std ;#define MAX 1000int flag[MAX] ;
int weight[MAX] ;
int n ;int main()
{while( scanf("%d",&n) != EOF ){int max ;for( int i = 0 ; i<n ; i++ )    scanf("%d",&weight[i]) ;scanf("%d",&max) ;//initmemset( flag , 0 , sizeof(flag ) ) ;sort( weight , weight+n ) ;//doint ans = 0 ;for( int i = 0 ; i<n ; i++ )if( flag[i] == 0 && weight[i] <= max ){int s = -1 ;for( int j = n-1 ; j>i ; j-- )if( flag[j] == 0 && weight[j] + weight[i] <= max ){s = j ;break ;}if( s != -1 ){flag[i] = flag[s] = 1 ;ans += 1 ;}else{flag[i] = 1;ans += 1 ;}}printf("%d\n",ans ) ;}return 0;
}

* 1005 *

Problem Description

给一个数n和k,把n分成两个整数a,b之和,即a+b=n(a,b>=0)。 要求使得a/k+b/k的值最小(除运算为整除),输出该值。
Input

输入t,表示t组数据(数据约为200组)。 接下来输入t行,每行两个数n,k,如上所述。其中(1<=n<=1e9,k<=n)

Output
每组数据输出相应结果。

Sample Input

2
1 1
5 3

Sample Output

1
1

分析:

这一道题,初步一看会觉得n/k = a/k + b/k , 其中(a+b==n )。但是呢,因为计算机中整形数之间的运算是会有截取的。所以,结果并不如我们所想。既然要结果最小,那么不如让a = k-1,那么结果肯定最小。


#include<stdio.h>int main()
{int T ;scanf("%d",&T) ;while( T-- ){int n , k ;scanf("%d %d",&n,&k) ;printf("%d\n",(n-k+1)/k) ;}return 0;
}

* 1006 *

Problem Description
众所周知,我是好人,不会出太难的题,题意简单得很,给你n条边的边长,问你能不能组成N边形,作为一个十足十的好人,提醒一下大家,想必大家都还记得三角形任意两边之和大于第三边吧…总共T(<=22)组数据,剩余数据都是不超过1000000的正整数.
Input
第一行组数T,第二行依次输入N,然后输入N条边的边长,相邻边长由1个空格间隔开
Output
如果可以请输出”YES”,否则”NO”,引号不用输出
Sample Input

2
3
1 1 1
3
2 2 2

Sample Output

YES
YES

分析:

如何判断n条边是否能构成n边型呢?依靠数学归纳法可得,任意n-1条边之后大于第n边即可。注意数据范围:1000000。要用O(nlogn)或者O(n)来跑。

#include<stdio.h>int main()
{int T ;scanf("%d",&T) ;while( T-- ){int  n ;scanf("%d",&n) ;int sum = 0 ; int max = -1 ;for( int i = 0 ; i<n ; i++ ){int t ;scanf("%d",&t) ;max = max > t? max : t ;sum += t ;}if( sum - max > max )   printf("YES\n") ;else                    printf("NO\n");}return 0 ;
}

* 1007 *

Problem Description

集训队里不仅学习氛围很好,大家相处也很融洽,有一天晚上,Cloud_x1、doubleegg、wingkou和Stubird在打锄大地,Stubird一边打牌一边在想隔天跟女粉丝见面,事情是这样的,那天有n个女粉丝来找他,告诉他明天早上会在哪里等他,给他准备了礼物,但是由于粉丝太多了,Stubird不可能跟所有粉丝都见面,所以他准备隔天走一条能够见到最多女粉丝的路。我们可以把地图看成是一个二维平面,Stubird从酒店门口出发,坐标为sx,sy,他选择了一个方向,然后只能沿着那个方向一直走,规定只有Stubird面对面见到女粉丝时才能拿到她的礼物。于是,Stubird就因为这个事情,想了一晚上,所以他也洗牌洗了一晚上,他当然不服气,所以他打算报复社会,把这个问题拿来考你。

Input
第一行输入一个样例数T

下面一行有n,sx,sy,代表n(1<=n<=1500000)个女粉丝,Stubird的位置sx,sy。

下面n行每行一个坐标,代表女粉丝的坐标。坐标都是0-1000的整数
Output
输出Stubird最多能跟多少个女粉丝见面,换行
Sample Input

1
2 1 1
2 2
3 3

Sample Output

2

分析:

首先要注意超时,对于1500000这个数据,只能用O(nlogn)的算法。这里说说我的思路。
首先重建坐标系,然后用向量的形式表示每一个点。
然后,缩短向量的长度,已便于判断相同方向。
然后,对向量进行快排。
最后,就算一下有多少个相同的即可。
注意的是,原点要单独处理。

这里给一个Input例子:
6 0 0
0 0
0 0
1 1
2 2
3 3
-1 -1

代码如下:


#include<stdio.h>
#include<stdlib.h>#define MAX 1500010//向量
struct vector
{int x,y ;
}stu[MAX];int cmp( const void *a, const void * b )
{struct vector * a1 = (struct vector *)a ;struct vector * b1 = (struct vector *)b ;if( a1->x != b1->x )return a1->x - b1->x ;  //降序排xelsereturn a1->y - b1->y ;
}int gcd( int a , int b )
{return b == 0 ? a : gcd( b , a %b ) ;
}int main()
{int T ;scanf("%d",&T) ;while( T-- ){int n , sx , sy ;int flag = 0 ;scanf("%d %d %d",&n,&sx,&sy ) ;for( int i = 0 ; i<n ; i++ ){//转移坐标系scanf("%d %d",&stu[i].x , &stu[i].y ) ;stu[i].x = stu[i].x - sx ;  stu[i].y = stu[i].y - sy ;if( stu[i].x == 0 && stu[i].y == 0 )    flag++ ;//缩短向量int g = abs( gcd( stu[i].x , stu[i].y ) ) ;if( g != 0 ){stu[i].x /= g ; stu[i].y /= g ;}else{if( stu[i].x == 0 ) stu[i].x = 0 ;else                stu[i].x = stu[i].x / abs(stu[i].x) ;if( stu[i].y == 0 ) stu[i].y = 0 ;else                stu[i].y = stu[i].y / abs(stu[i].y) ;}}//计算个数//先排一下序,nlogn的复杂度。相同的一定是排在一起的qsort( stu , n , sizeof(stu[0]) , cmp ) ;
/*for( int i = 0 ; i<n ; i++ )printf("x : %d y : %d\n",stu[i].x , stu[i].y );
*///O(n)来扫描int cnt = 1 , ans = 0 ;for( int i = 1 ; i<=n ; i++ )if( i == n ){if( ans < cnt ) ans = cnt ;}else{if( stu[i].x == stu[i-1].x && stu[i].y == stu[i-1].y )cnt++ ;else{if( ans < cnt ) ans = cnt ;cnt = 1 ;}}printf("%d\n",ans+flag) ;}return 0;
}

* 1008 *

Problem Description
Anna是一个公司老总,有一天她去参加一个竞标会,参与竞标的有A,B,C,D 4个公司。竞标规则是这样的,参与竞标的公司出价x(x必须为整数且在[1 1000000]范围内),然后用这个公式y=10.78*x+90.565,算出来他们的得分,得分比平均分大的公司会被淘汰,其他进入下一轮。Anna是A公司的老总,为了抵抗对手D公司,Anna说服了B,C两个公司联合起来,所以Anna可以控制A,B,C的出价。他们的目的是淘汰D公司,且A,B,C三个都不能被淘汰。你的目的是最大化A,B,C三个公司出价的最小值。
Input
第一行,一个T表示有T个测试样例,T最大为100000
接下来T行,一行一个正整数d,d在1-1000000内,表示d公司的出价。
Output
对每一个样例,输出一个数,占一行,表示淘汰D公司,且A,B,C三个都不被淘汰,最大化A,B,C公司出价的最小值。题目数据保证答案存在。
Sample Input

1
10

Sample Output

9

分析:

设A,B,C,D公司的出价为a,b,c,d。
由题意不难得出,下面两个不等式
1. a+b+c < 3*d
2. a,b,c < d
因为要让a,b,c的最小值最大的话,不妨取a+b+c = 3*d -1 。
我们来看下面的例子,可能会更好地理解。
当3*d -1 = 18时, a=6,b=6,c=6,是最佳。
当3*d -1 = 19时, a=7,b=6,c=6,是最佳。
当3*d -1 = 20时, a=7,b=7,c=6,是最佳。
当3*d -1 = 21时, a=7,b=7,c=7,是最佳。

可以猜出,当最小值取3*d-1时,可以最大化。

代码如下:

#include<stdio.h>int main()
{int T ;scanf("%d",&T);while( T-- ){int d ;scanf("%d",&d) ;printf("%d\n",(3*d-1)/3 ) ;}return 0;
}

* 1009*

Problem Description
“终有一天,耶和华的光会普照大地,旧的世界将会毁灭,新的世界将会产生。” ——《启示录·天启》

2096年11月8日,世界末日终于还是来临了。

而此时,世界上最后一个“神” —— sytrakl 也已经苏醒。他按照《圣经》的指引,找到了唯一能解救人类的“诺亚方舟”,并向全世界宣布任何人都可以进入方舟避难。
所有的人类知道消息后都疯狂了,他们纷纷赶来。由于怕触怒“神”,他们老老实实的在诺亚方舟的门前排起了队(方舟在队伍的最右边)。
sytrakl在英国的圣保罗大教堂沉睡了几百年,即使已经苏醒,却还保留着英国的“绅士风度”。 所以虽然方舟的体积足够大,但他还是决定让女人先行(即所有女人都在队伍右边)。于是他规定:
每一秒时间里,队伍里所有右边有男人的女人跟右边的男人调换位置。
sytrakl希望知道需要多少时间才能实现目的。然而sytrakl无所不能,但偏偏不懂编程。所以他找到了你(高兴吧!Excited!),希望你能帮他完成这个工作。
Ps:如果做不到,那你肯定药丸。
Input
题目有多组输入。每组将给出一串长度为n的字符串(1<=n<=1000000),有两种字符,‘M’表示这是一个男人,‘W’表示这是一个女人。
Output
输出总共需要多少时间。
Sample Input

WWMMM
WWM
MMWWW

Sample Output

4
2
0

分析:

细致分析一下,这里难的是如何实现。
从后面出发分析,先计算每个W到达终点的“距离”。然后再从后面往前面迭代,计算每个W到达终点的”时间“。


#include<stdio.h>
#include<string.h>#define MAX 1000001char str[MAX] ;
int site[MAX] ;int main()
{while( scanf("%s",str) != EOF ){memset( site , 0 , sizeof(site) ) ;int len = strlen(str) ;//计算每个women离最终位置的距离int k = 0 ;int cnt = 0 ; //计算多少个需要移动for( int i = len-1 ; i>=0 ; i-- ){if( str[i] == 'W' ){k++ ;site[i] = len - k - i ;if( site[i] != 0 ) cnt++ ;}}//需要移动if( cnt != 0 ){//从后面算起,迭代地计算前面的妇人需要等待的时间int pre = -1 ;for( int i = len -1 ; i>=0 ; i-- ){if( site[i] > 0 ){//第一个womenif( pre == -1 ){pre = i ;}else{if(  site[i] <= site[pre] ){site[i] =  site[pre]+1;}pre = i ;}}}printf("%d\n",site[pre]);}else //不需要移动{printf("0\n");}}return 0;
}

* 1010 *

Problem Description
有一天eagledoit收到了一封信,他打开一看,看到了一个字符串,在信的最后写着这么一句话:先把字符串循环右移n位,根据大小Hash一遍,然后转换成二进制,再根据格雷码解码,最后转换成十进制用数字五笔打出来,你就知道写的是什么了。他看完马上懵了,但他不是一个容易放弃的人,所以他决定用0x7fffffffffffffffffffffffff飞秒的时间去解决这个问题,第一步当然得把字符串右移,但是eagledoit并不会做,所以只能由你来帮他了。
Input
第一行输入一个样例T

下面每行输入一个字符串s和n,1<=strlen(s)<=1e7,n<=1e9
Output
每一行输出经过右移动的字符串
Sample Input

1
ab 1

Sample Output

ba

分析:

循环右移嘛~如果是出现在项目中,我建议是用循环链表做。如果是ACM题目嘛,如下即可:


#include<stdio.h>
#include<string.h>
#define MAX 10000007char str[MAX] ;int main()
{int T;scanf("%d",&T);while( T-- ){int mv ;scanf("%s",str) ;scanf("%d",&mv ) ;int len = strlen(str) ;int s = (len+mv) % len ;int s1 = len - s ;for( int i = s1  ; i<len ; i++  )printf("%c",str[i]) ;for( int i = 0 ; i<s1 ; i++ )printf("%c",str[i]);printf("\n");}return 0;
}

* 1011 *

Problem Description
给定6个矩形的长和宽hi和wi(1<=hi,wi<=1000),判断它们能否构成长方体的6个面。
Input
测试数据有多组,每组数据包括6行输入,每行输入2个整数,分别对应每个矩形的长和宽。
Output
若这些矩形能构成长方体的6个面,则输出”POSSIBLE”,否则输出”IMPOSSIBLE”。
Sample Input

2 3
1 2
3 2
2 1
3 1
1 3
1 3
2 3
1 3
1 3
3 2
2 3

Sample Output

POSSIBLE
IMPOSSIBLE

这一题就不提了。。

#include <stdio.h>
#include <stdlib.h>typedef struct
{int h,w;               //h和w分别存储每个矩形的长和宽
}rectangle;void swap(int &a,int &b)         //交换两个变量的值
{int c=a;a=b;b=c;
}int cmp(const void *a,const void *b)          //对每个矩形先按长再按宽进行降序排序
{rectangle *aa,*bb;aa=(rectangle *)a;bb=(rectangle *)b;if(aa->h!=bb->h)return bb->h-aa->h;elsereturn bb->w-aa->w;
}bool is_box(rectangle *l)                  //判断这些矩形能否构成盒子
{if(l[0].h!=l[1].h||l[0].w!=l[1].w)      //判断这些矩形有没有两两相等return false;if(l[2].h!=l[3].h||l[2].w!=l[3].w)return false;if(l[4].h!=l[5].h||l[4].w!=l[5].w)return false;if(l[0].h!=l[2].h)return false;if(l[0].w!=l[4].h)return false;if(l[2].w!=l[4].w)return false;return true;
}int main()
{//freopen ("1011input.txt", "r", stdin);//freopen ("1011output.txt", "w", stdout);int i;rectangle l[6];while(~scanf("%d%d",&l[0].h,&l[0].w)){for(i=1;i<6;i++)scanf("%d%d",&l[i].h,&l[i].w);for(i=0;i<6;i++)if(l[i].h<l[i].w)swap(l[i].h,l[i].w);qsort(l,6,sizeof(l[0]),cmp);if(is_box(l))printf("POSSIBLE\n");elseprintf("IMPOSSIBLE\n");}return 0;
}

好吧。就到这里吧。

2015GPNU新生赛题解相关推荐

  1. 2019年安徽大学ACM/ICPC实验室新生赛题解

    本文仅作个人收藏学习使用 题目及解析来源牛客竞赛网 //作者:王清楚 //链接:https://ac.nowcoder.com/discuss/351408?type=101&order=0& ...

  2. 2021暨南大学轩辕杯ACM程序设计新生赛题解

    title : 2021暨南大学轩辕杯ACM程序设计新生赛 date : 2021-12-12 tags : ACM,练习记录 author : Linno 题目链接:https://ac.nowco ...

  3. 2016中北大学ACM程序设计新生赛题解

    新生赛题目地址 a or an 输入字符串后判断第一个字符是不是'a','e','i','o','u',即可. #include<algorithm> #include <iostr ...

  4. 2021年浙江工商大学新生赛题解

    本篇中的题目顺序为预期难度顺序,并非比赛题目顺序 本篇中所有的"更好的优化"均为标准答案之外的思考,不使用此内容也可以通过题目 本文为拷贝版本,可能存在图片丢失等问题,不修复,请前 ...

  5. 2022济南大学acm新生赛题解

    通过答题情况的难度系数: 签到:ABL 简单:DGKQ 中等:CMN 困难:EFHIJOPRST A-和 算出n个数的和判断正负性即可!!! 发现很多同学的代码错误:要么sum未赋初值,要么数组大小定 ...

  6. 2019四川大学第二届SCUACM新生赛题解

    解题后记: 1.题是好题,虽然简单,都是学习C语言程序设计必学的内容. 2.通用化编程往往没有得到重视,尤其是初学的时候. 3.结构化程序设计非常重要,需要从开始就把握. 4.代码不仅要简洁,而且要极 ...

  7. 2021HAUT第五周新生赛题解

    目录 A.爱因斯坦光电效应 B.图书馆信息管理系统 C.这年头难道有人不喜欢签到吗 D.lsjp和他的小伙伴们 E.lwjq与国际象棋 F.lzlf的三角形绝技 G.lwyj的最短路径 H.cgg学长 ...

  8. 2017网络新生赛题解

    硬币翻转 题目描述 在桌面上有一排硬币,共N枚,每一枚硬币均为正面朝上.现在要把所有的硬币翻转成反面朝上,规则是每次可翻转任意N-1枚硬币(正面向上的被翻转为反面向上,反之亦然).求一个最短的操作序列 ...

  9. csust2020新生赛题解

    1.会长的数字 签到题,只要找输入的数字中有无某一位数字除以2等于0. 代码: #include<bits/stdc++.h> using namespace std; typedef l ...

最新文章

  1. error: Can not locate config makefile for product “xx“.
  2. robotframework - 运行报错提示 No keyword with name 'Open Browser' found.
  3. python3 with中异常的问题
  4. 七十六、Python | Leetcode二分查找和分治算法系列
  5. [Qt] 利用QtWebKit完成JavaScript访问C++对象
  6. Win11系统设置绿色护眼模式的方法
  7. PAT 1004 成绩排名 (20)(代码)
  8. ElasticSearch 比 MySQL 更适合复杂条件搜索
  9. 集成学习—Adaboost(论文研读)
  10. 大数据分析平台在企业的重要性
  11. 2015年硅谷最火技术十问
  12. 配置Skype for business 2015混合部署
  13. linux操作TF卡的命令
  14. xp系统dns服务器异常,电脑dns异常怎么修复,电脑dns异常修复方法介绍
  15. SQL AlawaysOn 之二:添加组织和域用户
  16. 英特尔服务器级cpu型号含义,新手必看 英特尔移动CPU命名规则解析
  17. 中介/代理,正/反向代理,直/间接代理,概念清晰解释
  18. 学校的计算机是作文,未来的电脑学校作文
  19. linux主机无线连接显示器,如何用Linux外接显示器或投影机
  20. 每日一threeJS(1)

热门文章

  1. 中小河流水文监测系统
  2. haimeiktv服务器系统,海媚 Haimei KBFG-9001 音效处理器
  3. error LINK2038:mismatch detected for '_MSC_VER':value '1900' doen't match value '1800'
  4. 【CAD2018一打开就出现致命错误怎么办?】
  5. 饿了么网页版测试用例
  6. python系统学习日记 L13 参数, 解包, 变量
  7. 空投盛宴:羊毛党的狂欢,项目方的尴尬 |链捕手
  8. 算法与数据结构——航班信息的查询与检索
  9. maven 点滴积累
  10. 微博app-Cookie分析