本打算作为2021年的最后一篇文章的...先整个框架,后面慢慢整理完吧。
我想了想,也不能一长段文字只是总结,也得总结一些对别人有用的东西,所以我决定先是总结一些错题好题,再去总结我2021年在计算机这方面的学习。
目录
PTA
PTA是我们平时写作业的平台,别的平台用的多的我对这个平台很是不习惯,但是作为天梯赛的OJ平台,我认为还是得从中总结出一些经验。下面来看题吧。
1.大笨钟
7-8 大笨钟 (10 分)
微博上有个自称“大笨钟V”的家伙,每天敲钟催促码农们爱惜身体早点睡觉。不过由于笨钟自己作息也不是很规律,所以敲钟并不定时。一般敲钟的点数是根据敲钟时间而定的,如果正好在某个整点敲,那么“当”数就等于那个整点数;如果过了整点,就敲下一个整点数。另外,虽然一天有24小时,钟却是只在后半天敲1~12下。例如在23:00敲钟,就是“当当当当当当当当当当当”,而到了23:01就会是“当当当当当当当当当当当当”。在午夜00:00到中午12:00期间(端点时间包括在内),笨钟是不敲的。
下面就请你写个程序,根据当前时间替大笨钟敲钟。
输入格式:
输入第一行按照
hh:mm
的格式给出当前时间。其中hh
是小时,在00到23之间;mm
是分钟,在00到59之间。输出格式:
根据当前时间替大笨钟敲钟,即在一行中输出相应数量个
Dang
。如果不是敲钟期,则输出:Only hh:mm. Too early to Dang.
其中
hh:mm
是输入的时间。输入样例1:
19:05
结尾无空行
输出样例1:
DangDangDangDangDangDangDangDang
结尾无空行
输入样例2:
07:05
输出样例2:
Only 07:05. Too early to Dang.
其实主要是要看懂题目,整点敲整点数,过了整点多敲一下,0~12点不敲,就这么简单
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int h, m, cnt;//cnt表示敲钟次数
scanf("%d:%d", &h, &m);
if (h >= 12 && h <= 23)
{
cnt = h - 12;
if (m > 0)cnt++;
for (int i = 0; i < cnt; i++)cout << "Dang";
}
else printf("Only %02d:%02d. Too early to Dang.", h, m);
return 0;
}
2.水仙花数
7-1 水仙花数 (5 分)
水仙花数是指一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身。例如:153=13+53+33。 本题要求编写程序,计算所有N位水仙花数。
输入格式:
输入在一行中给出一个正整数N(3≤N≤7)。
输出格式:
按递增顺序输出所有N位水仙花数,每个数字占一行。
输入样例:
3
结尾无空行
输出样例:
153 370 371 407
结尾无空行
这个水仙花数有些不一样,正常操作的话N顶满到7就会超时,所以要想办法优化一下
#include<stdio.h>
#include<math.h>
int main()
{
int n;
scanf("%d",&n);//n>=3
int a,b;
a=pow(10,n-1);
b=pow(10,n);//a,b为数字的区间
int s[10],k;
for(k=0;k<10;k++)
{
s[k]=pow(k,n);//定义此数组中存储有1-9的n次方,这样可以直接调用
}
int i;
for(i=a;i<=b;i++)
{
int j=i;
int sum=0;//while循环后sum不为0,需重新给定
while(j>0)
{
sum=sum+s[j%10];
j /=10;
}
if(sum==i)
{
printf("%d\n",i);
}
}
return 0;
}
//代码来自https://blog.csdn.net/hand_up/article/details/121083429
3.黑洞数
7-9 黑洞数 (12 分)
黑洞数也称为陷阱数,又称“Kaprekar问题”,是一类具有奇特转换特性的数。
任何一个各位数字不全相同的三位数,经有限次“重排求差”操作,总会得到495。最后所得的495即为三位黑洞数。所谓“重排求差”操作即组成该数的数字重排后的最大数减去重排后的最小数。(6174为四位黑洞数。)
例如,对三位数207:
- 第1次重排求差得:720 - 27 = 693;
- 第2次重排求差得:963 - 369 = 594;
- 第3次重排求差得:954 - 459 = 495;
以后会停留在495这一黑洞数。如果三位数的3个数字全相同,一次转换后即为0。
任意输入一个三位数,编程给出重排求差的过程。
输入格式:
输入在一行中给出一个三位数。
输出格式:
按照以下格式输出重排求差的过程:
序号: 数字重排后的最大数 - 重排后的最小数 = 差值
序号从1开始,直到495出现在等号右边为止。
输入样例:
123
结尾无空行
输出样例:
1: 321 - 123 = 198 2: 981 - 189 = 792 3: 972 - 279 = 693 4: 963 - 369 = 594 5: 954 - 459 = 495
结尾无空行
没多难,只是一开始重排求差没思路
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
int n, Min, Max, a[3];
cin >> n;
for (int t = 1;; t++) {
a[0] = n / 100; a[1] = n / 10 % 10; a[2] = n % 10;
sort(a, a + 3);
Max = a[2] * 100 + a[1] * 10 + a[0];
Min = a[0] * 100 + a[1] * 10 + a[2];
n = Max - Min;
printf("%d: %d - %d = %d\n", t, Max, Min, n);
if (n == 495) break;
}
return 0;
}
//代码参考https://blog.csdn.net/qq_39427510/article/details/82117466
4.选择排序
7-15 选择排序 (15 分)
选择排序
,从头至尾扫描序列,找出最小的一个元素,和第一个元素交换,接着从剩下的元素中继续这种选择和交换方式,最终得到一个有序序列。输入格式:
输入在第1行中给出N(1<N≤100),在第2行中给出N个待排序的整数,数字间以空格分隔,并保证数字没有重复的出现。
输出格式:
给出选择排序每一遍后的中间结果数列,数字间以空格分隔,但末尾不得有多余空格。
注意:当排序完成时应立即停止
。输入样例1:
7 4 5 7 6 3 2 1
结尾无空行
输出样例1:
1 5 7 6 3 2 4 1 2 7 6 3 5 4 1 2 3 6 7 5 4 1 2 3 4 7 5 6 1 2 3 4 5 7 6 1 2 3 4 5 6 7
结尾无空行
输入样例2:
5 1 2 3 5 4
结尾无空行
输出样例2:
1 2 3 4 5
结尾无空行
别问,问就是sort用多了
#include<iostream>
using namespace std;
int a[105];
int main()
{
int n,m,t,w;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
for(int i=0;i<n;i++)
{
m=a[i];
w=i;
for(int j=i+1;j<n;j++)
{
if(a[j]<m)
{
m=a[j];
w=j;
}
}
if(w!=i)//如果未发生交换
{
t=a[i];
a[i]=m;
a[w]=t;
for(int k=0;k<n;k++)
{
if(k==n-1)cout<<a[k]<<endl;
else cout<<a[k]<<' ';
}
}
}
return 0;
}
5.6翻了
L1-2 6翻了 (15 分)
“666”是一种网络用语,大概是表示某人很厉害、我们很佩服的意思。最近又衍生出另一个数字“9”,意思是“6翻了”,实在太厉害的意思。如果你以为这就是厉害的最高境界,那就错啦 —— 目前的最高境界是数字“27”,因为这是 3 个 “9”!
本题就请你编写程序,将那些过时的、只会用一连串“6666……6”表达仰慕的句子,翻译成最新的高级表达。
输入格式:
输入在一行中给出一句话,即一个非空字符串,由不超过 1000 个英文字母、数字和空格组成,以回车结束。
输出格式:
从左到右扫描输入的句子:如果句子中有超过 3 个连续的 6,则将这串连续的 6 替换成 9;但如果有超过 9 个连续的 6,则将这串连续的 6 替换成 27。其他内容不受影响,原样输出。
输入样例:
it is so 666 really 6666 what else can I say 6666666666
结尾无空行
输出样例:
it is so 666 really 9 what else can I say 27
结尾无空行
天梯赛的题目,字符串是重点
#include<iostream>
#include<string>
using namespace std;
int main()
{
string a;
getline(cin, a);
int cnt = 0;
for (int i = 0; i < a.size(); i++)
{
if (a[i] == '6')
{
cnt++;//如果说有6这个字符,个数就加一
}
else//没遇到连续的6就中断,然后按题目要求统计
{
if (cnt > 9) printf("27");
else if (cnt > 3) printf("9");
else while (cnt--) printf("6");
if (i == len) break;
cnt = 0;
printf("%c", a[i]);//其他的情况就按照原格式输出
}
}
return 0;
}
6.吉老师的回归
7-4 吉老师的回归 (15 分)
曾经在天梯赛大杀四方的吉老师决定回归天梯赛赛场啦!
为了简化题目,我们不妨假设天梯赛的每道题目可以用一个不超过 500 的、只包括可打印符号的字符串描述出来,如:
Problem A: Print "Hello world!"
。众所周知,吉老师的竞赛水平非常高超,你可以认为他每道题目都会做(事实上也是……)。因此,吉老师会按照顺序看题并做题。但吉老师水平太高了,所以签到题他就懒得做了(浪费时间),具体来说,假如题目的字符串里有
qiandao
或者easy
(区分大小写)的话,吉老师看完题目就会跳过这道题目不做。现在给定这次天梯赛总共有几道题目以及吉老师已经做完了几道题目,请你告诉大家吉老师现在正在做哪个题,或者吉老师已经把所有他打算做的题目做完了。
提醒:天梯赛有分数升级的规则,如果不做签到题可能导致团队总分不足以升级,一般的选手请千万不要学习吉老师的酷炫行为!
输入格式:
输入第一行是两个正整数 N,M (1≤M≤N≤30),表示本次天梯赛有 N 道题目,吉老师现在做完了 M 道。
接下来 N 行,每行是一个符合题目描述的字符串,表示天梯赛的题目内容。吉老师会按照给出的顺序看题——第一行就是吉老师看的第一道题,第二行就是第二道,以此类推。
输出格式:
在一行中输出吉老师当前正在做的题目对应的题面(即做完了 M 道题目后,吉老师正在做哪个题)。如果吉老师已经把所有他打算做的题目做完了,输出一行
Wo AK le
。
同样也是天梯赛的字符串题目
#include<iostream>
#include<string>
using namespace std;
int main()
{
int n, m, flag = 1;
string str;
cin >> n >> m;//输入
getchar();//!这里注意!cin后面要用getline要把回车弄掉!
while (n--)
{
getline(cin, str);//输入字符串
if (str.find("qiandao") != -1 || str.find("easy") != -1);//如果符合则无输出
else
{
if (m == 0)//剩余做题数==0
{
cout << str;//输出字符串
flag = 0;
break;//退出循环
}
m--;//做题数
}
}
if (flag)
cout << "Wo AK le" << endl;//如果标志未改变
return 0;
}
其他平台
1.玲娜贝尔的数组
来源:牛客网
题目描述
玲娜贝尔有一个非负数的数组:a1,a2,...,an。对于每一个1≤i≤n,她都找到一个非负整数xi=max(0,a1,...,ai-1)。ai-1表示a数组的第(i-1)个数据,注意,对于i=1,xi=0。
例如,如果玲娜贝尔有一个数组a={0,1,2,0,3},那么x={0,0,1,2,2}。
然后,她计算一个数组,b1,b2,...,bn:bi=ai-xi。
例如,如果玲娜贝尔有一个数组a={0,1,2,0,3},那么
b={0-0,1-0,2-1,0-2,3-2}={0,1,1,-2,1}。玲娜贝尔给你的数值是b1,b2,...,bn,并要求你还原数值a1,a2,...,an。你能帮助她解决这个问题吗?
输入描述:
第一行包含一个整数n(3≤n≤200000)玲娜贝尔的数组中元素的数量。 下一行包含n个整数,b1,b2,...,bn(-1000000000≤bi≤1000000000)。 保证对于给定的数组b,有一个解a1,a2,...,an,对于其中的所有元素,以下情况为真:0≤ai≤1000000000。 输出描述:打印n个整数,a1,a2,...,an(0≤ai≤1000000000),这样如果按照语句计算x,b1将等于a1-x1,b2将等于a2-x2,...,bn将等于an-xn。 可以保证,对于给定的测试,至少存在一个解。可以证明,该解决方案是唯一的。示例1
输入
5 0 1 1 -2 1 输出 0 1 2 0 3 说明 第一个测试是在问题陈述中描述的。示例2
输入
3 1000 999999000 -1000000000 输出 1000 1000000000 0 说明 在第二个测试中,如果玲娜贝尔有一个数组a={1000,1000000000,0},那么x={0,1000,1000000000},b={1000-0,1000000000-1000,0-1000000000}={1000,99999000,-1000000000}。示例3
输入
5 2 1 2 2 3输出
2 3 5 7 10
上学姐的代码,因为码风我太喜欢了
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
int b[300000];
int a[300000];
int x[300000];
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(x,0,sizeof(x));
for(int i = 1 ; i <= n ; i ++) scanf("%d",&b[i]);
for(int i = 1 ; i <= n ; i ++)
{
x[i] = max(a[i-1],x[i-1]);
a[i] = x[i] + b[i];
cout << a[i] <<" ";
}
return 0;
}
2.A+B
来源:牛客网
题目描述
众所周知王某最喜欢写A + B的题了,钢哥对于他这种怠惰的行为非常的不满,所以给他出了一个只有11 bit 带符号的加法问题,即数字的取值范围为[−210 ,210−1]
现在给你A和B请算出A + B的结果
输入描述:
本题采用多组输入,每一行给两个整数分别代表A, B(−1024 ≤ A, B ≤ 1023)输出描述:
每一行输出一个A + B的结果示例1
输入
1 1 1 1023 2 1023 -1 -1024输出
2 -1024 -1023 1023
当时没做出来真的是老蠢了
#include<iostream>
using namespace std;
int main()
{
int a,b,c;
while(cin>>a>>b)
{
c=a+b;
while(c<-1024||c>1023)
{
if(c==1024)
c=-c;
else if(c>1024)
c=c-2048;
else if(c<-1024)
{
c=c+2048;
}
}
cout<<c<<endl;
}
return 0;
}
3.搬家了
来源:牛客网
题目描述
韬神在工作了一段时间后,手头上有了一些积蓄,众所周知,韬神从不谈恋爱,所以韬神用这些钱付了新房子的首付,他现在准备搬家了,现在他有N项物品,大小分别为s1、s2、…、si、…、sN,其中si为满足1≤si≤100的整数,韬神要把这些物品装入到容量为100的一批箱子(序号1-N)中去,韬神有自己独特的装箱方法:对每项物品, 顺序扫描箱子,把该物品放入足以能够容下它的第一个箱子中去,现在请你写一个程序模拟这种装箱过程,并输出每个物品所在的箱子序号,以及放置全部物品所需的箱子数目。
输入描述:
输入第一行给出物品个数N(≤1000);第二行给出N个正整数si(1≤si≤100,表示第i项物品的大小)。输出描述:
按照输入顺序输出每个物品的大小及其所在的箱子序号,每个物品占1行,最后一行输出所需的箱子数目。示例1
输入
8 60 70 80 90 30 40 10 20输出
60 1 70 2 80 3 90 4 30 1 40 5 10 1 20 2 5
咳咳...从一百往下减就省事很多...
#include<bits/stdc++.h>
using namespace std;
int a[1010],s[1010],x[1010];
int main()
{
int n,cnt=1;
cin>>n;
for(int i=0;i<1010;i++)
{
a[i]=100;
}
for(int i=0;i<n;i++)
{
cin>>s[i];
}
for(int i=0;i<n;i++)
{
for(int j=1;j<=n;j++)
{
if(s[i]<=a[j])
{
a[j]-=s[i];
x[i]=j;
if(j>cnt)cnt=j;
break;
}
}
}
for(int i=0;i<n;i++)
{
cout<<s[i]<<' '<<x[i]<<endl;
}
cout<<cnt;
return 0;
}
大一上有感
大一上一学期下来,进步不大,但是经历颇多。
先是经历了校赛,发现自己要学的不只是语法,还要多加练习提升思维,并且要学算法。
后面认识了一位非常非常好的学长,带我体会算法,教我程序设计竞赛的技巧和经验,告诉我不要着急学算法,重要的是打开自己的思维。
经历了一次又一次的新生考核,一次又一次地自我怀疑,总是问自己为什么脑子这么不好使。明明比别人努力多一个月,比赛结果却总是不尽人意。我好像就是比别人笨这么一点,好像别人只要理科思维好一点,就能轻轻松松赶超我了。一次次的新生赛让我感觉自己之前的努力跟没用一样,总是很迷茫到底什么时候才能捡回那一丝丝的自信。
看了Tourist和吉司机的神级手速,看了楼教主神一般的经历,也看了前几年的ICPC总决赛录像,发现自从格局打开之后,积极性也在不断消减,总感觉自己打不出什么名堂,好像还不如努努力做点开发。每每被网络赛中的OI选手AK之后,都在长叹:这怎么比啊,人家七十分钟AK了我才开第三题。
想了一下,既然选择了这条路,终究还是不要消减对比赛的热情,该努力就努力,至于脑子不好,思维不够开阔,也只能等以后的结果。我想,如果能努努力打过一两个OI选手,那是不是有种以凡人之躯比肩神明的感觉呢?
多思考,多练吧,不要一道题看完没有切口就直接放弃,对比赛要有持续的热情,但是终究不要把比赛当成全部。