GPLT团体程序设计天梯赛-练习集 L1-001~L1-010

L1-001 Hello World (5 分)


这道超级简单的题目没有任何输入。

你只需要在一行中输出著名短句Hello World!就可以了。


输入样例


输出样例

Hello World!

作者:陈越
单位:浙江大学
代码长度限制:16 KB
时间限制:400 ms
内存限制:64 MB



PZ.cpp

#include<cstdio>
int main()
{
	printf("Hello World!");
	return 0;
}






L1-002 打印沙漏 (20 分)


本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个*,要求按下列格式打印

*****
 ***
  *
 ***
*****

所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差\(2\);符号数先从大到小顺序递减到\(1\),再从小到大顺序递增;首尾符号数相等。

给定任意\(N\)个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。


输入格式

输入在一行给出\(1\)个正整数\(N(\leqslant 1000)\)和一个符号,中间以空格分隔。


输出格式

首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。


输入样例

19 *

输出样例

*****
 ***
  *
 ***
*****

作者:陈越
单位:浙江大学
代码长度限制:16 KB
时间限制:400 ms
内存限制:64 MB



PZ's Solution

1.设定变量maxs为第一行需要输出的、最大的 符号数;

2.遍历寻找maxs的最大值,对于总的符号数,有公式\(\frac{(1+maxs)*(\lfloor\frac{maxs}{2}\rfloor+1)}{2}*2-1\)

公式左边为等差数列求和,\(*2-1\)是因为要组成沙漏,可以看成上下镜像后将其中一个*去掉即可;

3.对于空格数量,设当前行需要输出字符数量为j,则需要输出的空格数量为\(\lfloor\frac{maxs-j}{2}\rfloor\)

4.对于剩余符号数,即\(n-\frac{(1+maxs)*(\lfloor\frac{maxs}{2}\rfloor+1)}{2}*2-1\)


PZ.cpp

#include<cstdio>
int main()
{
	int n,maxs=1; char ch; scanf("%d %c",&n,&ch);
	for(;;maxs+=2){
		if(n<(1+(maxs+2))*((maxs+2)/2+1)-1) break;
	}
	for(int i=maxs;i>=1;i-=2){
		for(int j=1;j<=(maxs-i)/2;++j) printf(" ");
		for(int k=1;k<=i;++k) printf("%c",ch);
		puts("");
	}
	for(int i=3;i<=maxs;i+=2){
		for(int j=1;j<=(maxs-i)/2;++j) printf(" ");
		for(int k=1;k<=i;++k) printf("%c",ch);
		puts("");
	}
	printf("%d",n-((1+maxs)*(maxs/2+1)-1));
	return 0;
}






L1-003 个位数统计 (15 分)


给定一个 \(k\) 位整数 \(N=d_{k−1}10^{k−1}+⋯+d_{1}10^1+d_0(0 \leqslant d_i \leqslant 9, i=0,⋯,k−1, d_{k−1}>0)\),请编写程序统计每种不同的个位数字出现的次数。例如:给定 \(N=100311\),则有 \(2\)\(0\)\(3\)\(1\),和 \(1\)\(3\)


输入格式

每个输入包含 \(1\) 个测试用例,即一个不超过 \(1000\) 位的正整数 \(N\)


输出格式

\(N\) 中每一种不同的个位数字,以 \(D:M\) 的格式在一行中输出该位数字 \(D\) 及其在 \(N\) 中出现的次数 \(M\)。要求按 \(D\) 的升序输出。


输入样例

100311

输出样例

0:2
1:3
3:1

作者:陈越
单位:浙江大学
代码长度限制:16 KB
时间限制:400 ms
内存限制:64 MB



PZ's Solution

1.因为\(N\)的位数很大,而且只关注每位上是什么数字,故将\(N\)作为string读入;

2.随后记录数字出现次数即可;


PZ.cpp

#include<iostream>
using namespace std;
int num[10];
int main()
{
	string n; cin>>n;
	for(int i=0;i<n.size();++i)
		++num[n[i]-'0'];
	for(int i=0;i<=9;++i)
		if(num[i]) cout<<i<<":"<<num[i]<<endl;
	return 0;
}






L1-004 计算摄氏温度 (5 分)


给定一个华氏温度\(F\),本题要求编写程序,计算对应的摄氏温度\(C\)。计算公式:\(C=5×(F−32)/9\)。题目保证输入与输出均在整型范围内。


输入格式

输入在一行中给出一个华氏温度。


输出格式

在一行中按照格式Celsius = C输出对应的摄氏温度\(C\)的整数值。


输入样例

150

输出样例

Celsius = 65

作者:陈越
单位:浙江大学
代码长度限制:16 KB
时间限制:400 ms
内存限制:64 MB



PZ.cpp

#include<cstdio>
int main(){
	int F; scanf("%d",&F);
	printf("Celsius = %d",5*(F-32)/9);
	return 0;
}






L1-005 考试座位号 (15 分)


每个 PAT 考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座位就座。但有些考生迟到了,试机已经结束,他们只能拿着领到的试机座位号码求助于你,从后台查出他们的考试座位号码。


输入格式

输入第一行给出一个正整数 \(N(\leqslant 1000)\),随后 \(N\) 行,每行给出一个考生的信息:准考证号 试机座位号 考试座位号。其中准考证号由 \(16\) 位数字组成,座位从 \(1\)\(N\) 编号。输入保证每个人的准考证号都不同,并且任何时候都不会把两个人分配到同一个座位上。

考生信息之后,给出一个正整数 \(M( \leqslant N)\),随后一行中给出 \(M\) 个待查询的试机座位号码,以空格分隔。


输出格式

对应每个需要查询的试机座位号码,在一行中输出对应考生的准考证号和考试座位号码,中间用 \(1\) 个空格分隔。


输入样例

4
3310120150912233 2 4
3310120150912119 4 1
3310120150912126 1 3
3310120150912002 3 2
2
3 4

输出样例

3310120150912002 2
3310120150912119 1

作者:陈越
单位:浙江大学
代码长度限制:16 KB
时间限制:200 ms
内存限制:64 MB



PZ's Solution

1.直接使用STL中的map,设每个学生有一个学生序号\(i(1\leqslant i \leqslant n)\)

2.map让每个试机座位号都对应一个学生序号,每次寻找直接输出对应学生序号下的准考证号和考试座位号即可;


PZ.cpp

#include<cstdio>
#include<map>
using namespace std;
const int N=1010;
map<int,int>mp;
long long zhun_kao[N];
int shi_ji[N],kao_shi[N];
int main(){
	int n; scanf("%d",&n);
	while(n--){
		scanf("%lld %d %d",&zhun_kao[n],&shi_ji[n],&kao_shi[n]);
		mp[shi_ji[n]]=n;
	}
	int m; scanf("%d",&m);
	while(m--){
		int Shi_Ji; scanf("%d",&Shi_Ji);
		printf("%lld %d\n",zhun_kao[mp[Shi_Ji]],kao_shi[mp[Shi_Ji]]);
	}
	return 0;
}






L1-006 连续因子 (20 分)


一个正整数 \(N\) 的因子中可能存在若干连续的数字。例如 \(630\) 可以分解为 \(3×5×6×7\),其中 \(5、6、7\) 就是 \(3\) 个连续的数字。给定任一正整数 \(N\),要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。


输入格式

输入在一行中给出一个正整数 \(N(1<N<2^{31})\)


输出格式

首先在第 \(1\) 行输出最长连续因子的个数;然后在第 \(2\) 行中按 因子1*因子2*……*因子k 的格式输出最小的连续因子序列,其中因子按递增顺序输出,\(1\) 不算在内。


输入样例

630

输出样例

3
5*6*7

作者:陈越
单位:浙江大学
代码长度限制:16 KB
时间限制:400 ms
内存限制:64 MB



Solution

思路来自林夕-梦的天梯赛 L1-006 连续因子 (模拟)

一开始读错题了,以为是要找约数,一个最大连续、一个最小连续
但实际上,就是单纯让分解\(N\),求出一个最长连续因子个数,并输出其字典序最小序列;

1.因为需要分解\(N\),考虑到\(2^{31}=2,147,483,648<13!=6,227,020,800\),且题目要求不考虑\(1\),则序列最长长度即为\(11\)

首先它到不了13,所以最大为\(12!\),又忽略\(1\),故为\(11\)

2.让序列从最长开始遍历,让因子从\(2\)遍历到\(\sqrt N\),并按照序列长度累乘(因为如果序列中有数\(>sqrt N\),则可能有\(\sqrt N * \sqrt{N+1} >N\),显然非法);

3.这样,当找到一组合法解时,此解必然为最长序列,且其字典序最小;


std.cpp

#include<cstdio>
#define ll long long
int main(){
	int n; scanf("%d",&n);
	for(int len=11;len>=1;--len){
		for(ll i=2;i*i<=n;++i){
			ll res=1;
			for(int j=i;j<=i+len-1;++j){
				res*=j;
				if(res>n) break;
			}
			if(n%res==0){
				printf("%d\n",len);
				for(int j=i;j<=i+len-1;++j)
					printf("%d%c",j,j==i+len-1? 0 : '*');
				return 0;
			}
		}
	}
	printf("1\n%d",n);
	return 0;
}






L1-007 念数字 (10 分)


输入一个整数,输出每个数字对应的拼音。当整数为负数时,先输出fu字。十个数字对应的拼音如下:

0: ling
1: yi
2: er
3: san
4: si
5: wu
6: liu
7: qi
8: ba
9: jiu

输入格式

输入在一行中给出一个整数,如:1234

提示:整数包括负数、零和正数。


输出格式

在一行中输出这个整数对应的拼音,每个数字的拼音之间用空格分开,行末没有最后的空格。如 yi er san si


输入样例

-600

输出样例

fu liu ling ling

作者:翁恺
单位:浙江大学
代码长度限制:16 KB
时间限制:400 ms
内存限制:64 MB



PZ's Solution

1.使用map预处理对应拼音,使用string读入\(N\)

2.随后遍历,注意行末没有空格即可;


PZ.cpp

#include<cstdio>
#include<iostream>
#include<map>
using namespace std;
map<int,string>mp;
int main(){
	mp[0]="ling";
	mp[1]="yi";
	mp[2]="er";
	mp[3]="san";
	mp[4]="si";
	mp[5]="wu";
	mp[6]="liu";
	mp[7]="qi";
	mp[8]="ba";
	mp[9]="jiu";
	mp[10]="fu";
	string n; cin>>n;
	for(int i=0;i<n.size();++i){
		if(n[i]=='-') cout<<mp[10];
		else cout<<mp[n[i]-'0'];
		printf("%c",i==n.size()-1 ? 0 : ' ');
	}
	return 0;
}






L1-008 求整数段和 (10 分)


给定两个整数\(A\)\(B\),输出从\(A\)\(B\)的所有整数以及这些数的和。


输入格式

输入在一行中给个整数\(A\)\(B\),其中\(−100 \leqslant A \leqslant B \leqslant 100\),其间以空格分隔。


输出格式

首先顺序输出从A到B的所有整数,每\(5\)个数字占一行,每个数字占\(5\)个字符宽度,向右对齐。最后在一行中按Sum = X的格式输出全部数字的和X


输入样例

-3 8

输出样例

   -3   -2   -1    0    1
    2    3    4    5    6
    7    8
Sum = 30

作者:杨起帆
单位:浙大城市学院
代码长度限制:16 KB
时间限制:400 ms
内存限制:64 MB



PZ's cpp

#include<cstdio>
int main(){
	int a,b; scanf("%d %d",&a,&b);
	int i=a;
	while(i<=b){
		for(int j=1;j<=5;++j){
			printf("%5d",i); if(j==5) puts("");
			++i;
			if(i==b+1){
				if(j!=5) puts("");
				printf("Sum = %d",(a+b)*(b-a+1)/2);
				return 0;
			}
		}
	}
	return 0;
}






L1-009 N个数求和 (20 分)


本题的要求很简单,就是求N个数字的和。麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和也必须是有理数的形式。


输入格式

输入第一行给出一个正整数N\(( \leqslant 100)\)。随后一行按格式a1/b1 a2/b2 ...给出N个有理数。题目保证所有分子和分母都在长整型范围内。另外,负数的符号一定出现在分子前面。


输出格式

输出上述数字和的最简形式 —— 即将结果写成整数部分 分数部分,其中分数部分写成分子/分母,要求分子小于分母,且它们没有公因子。如果结果的整数部分为\(0\),则只输出分数部分。


输入样例1

5
2/5 4/15 1/30 -2/60 8/3

输出样例1

3 1/3

输入样例2

2
4/3 2/3

输出样例2

2

输入样例3

3
1/3 -1/6 1/8

输出样例3

7/24

作者:陈越
单位:浙江大学
代码长度限制:16 KB
时间限制:400 ms
内存限制:64 MB



Solution

思路来自 ChangeG 的N个数求和(PTA)

1.对当前读入的有理数,直接与之前输入的有理数相加,再化为最简形式;

2.设之前输入的有理数的和的形式为\(\frac{a_{sum}}{b_{sum}}\),当前读入的有理数为\(\frac{a}{b}\)

3.显然通分结果为\(b_{sum}*b\),则通分后,两数分别为\(\frac{a_{sum}*b}{b_{sum}*b},\;\frac{a*b_{sum}}{b*b_{sum}}\),则合并结果为\(\frac{a_{sum}*b+a*b_{sum}}{b_{sum}*b}\)

4.对于累加后的 新的\(\frac{a_{sum}}{b_{sum}}\),设\(tmp=gcd(a_{sum},b_{sum})\),则\(tmp\)\(a_{sum},b_{sum}\)的最大公因子,上下同除\(tmp\)可以使分数最简化;

5.最后对整数部分进行判断,注意输出格式即可;

原博主这么写过:-3/2的时候他们的结果都是-1 1/-2,但他给出的代码会输出-1 1/2,本人认为答案应该为-1 -1/2,因为一般认为最简形式其实应该为整数部分+分数部分,所以分数部分也应是负数;


std.cpp

#include<cstdio>
#include<algorithm>
#define ll long long
ll a,b,suma,sumb=1;
ll gcd(ll x,ll y){ return y==0 ? x : gcd(y,x%y); }
int main(){
	int n; scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%lld/%lld",&a,&b);
		suma=suma*b+a*sumb;
		sumb=sumb*b;
		ll tmp=gcd(suma,sumb);
		suma/=tmp; sumb/=tmp;
	}
	if(suma==0) puts("0");//特判0
	else {
		if(suma/sumb) printf("%lld",suma/sumb);
		if(suma%sumb){
			if(suma/sumb) printf(" ");//格式格式
			if(suma*sumb<0) printf("-");
			printf("%lld/%lld\n",abs(suma%sumb),abs(sumb));
		}
	}
	return 0;
}






L1-010 比较大小 (10 分)


本题要求将输入的任意\(3\)个整数从小到大输出。


输入格式

输入在一行中给出\(3\)个整数,其间以空格分隔。


输出格式

在一行中将\(3\)个整数从小到大输出,其间以->相连。


输入样例

4 2 8

输出样例

2->4->8

作者:杨起帆
单位:浙大城市学院
代码长度限制:16 KB
时间限制:400 ms
内存限制:64 MB



PZ.cpp

#include<cstdio>
#include<algorithm>
int main(){
	int x[3]; scanf("%d %d %d",&x[0],&x[1],&x[2]);
	std::sort(x,x+3);
	printf("%d->%d->%d",x[0],x[1],x[2]);
	return 0;
}
posted @ 2021-03-02 23:17  PotremZ  阅读(785)  评论(0编辑  收藏  举报