学习目标:
- 上午9:00-14:00完赛第二届全国大学生算法设计与编程挑战赛冬季赛,晚上19:00收看直播讲解并总结。
- 雅思听力语料库听写Chapter 5 Test 5并批改。
学习内容:
随笔记录:
于2021年3月14日π节凌晨2:04,校OJ累计ac120题,暂列18名,准备在蓝桥杯国赛前ac300题,冲oj榜1,但是还是以高数为主吧,本周把第四章结束!全国大学生英语竞赛去年拿了国一,今天组委会能否允许参赛还未知,学习英语有所懈怠。
第二届全国大学生算法设计与编程挑战赛冬季赛起晚了,结果不佳,仅AC4题,铜奖无望,榜一大佬AC9题,感觉题目质量很好,晚上听完直播讲解,把题解与分析补上。
codeblocks的代码页面变成了全屏,调试信息都不见了。
解决方法:View->perspective->Code::Blocks default
塔
Description
你在最后那场博弈中败下阵来,却意外穿越到了海拉尔大陆!是你吗林克?初来到海拉尔大陆的你,有些许的局促,但当你看到塔,或许一切的一切都迎刃而解。一个层高为n的字母塔的定义为:
共n行,由字母组成的等腰三角形。塔顶为第一层,且只有一个大写字母A;下面每一层都比上面一层多两个字母。每一层都是左右对称。对于第i层,前i个字母由大写字母表中A~第i个字母顺序组成。为了稳住局面,样例给出了层高为5的字母塔,请你输出层高2626的字母塔。
Input
TIPS:此题是一道程序填空题,下面会给出此题正确代码的挖空版本,选手可以根据提示对代码进行完善。
Output
输出高度为 26 的塔。
Sample Input 1
TIPS:此题是一道程序填空题,下面会给出此题正确代码的挖空版本,选手可以根据提示对代码进行完善。 下面给出层高为5的塔的样例输出
Sample Output 1
A ABA ABCBA ABCDCBA ABCDEDCBA
- 思路:对于每一层第i层考虑,总共分为三步,第一步:每行输入n-i个空格;第二步:从1到i依次输出‘A’到‘A+i-1’;第三歩:从i-1到1依次输出倒序的字母。
- 注意,没行过后要换行,对于大写字母表中第i个字符,可以使用’A’+i-1得到。
#include <stdio.h>
/***********************************
观察题目样例给出的高为5层的塔,可以得出以下几个规律
对于一个高为n层的塔而言,首先设最上面一层(顶层)为第一层。
1. 对于第i层而言,其字符的排列规律为:大写字母表中从第1个字符(A)~第i个字符,后又倒序从第i-1个字符~第1个字符(A)。
2. 第1~n-1层每层前都有空格,具体而言,对于第i行,字符前面的空格个数为n-i个。
找出以上规律后,我们就可以根据这些规律构造出答案:层高26的塔。
TIPS:
大写字母'A'为大写字母表第一个字符
对于大写字母表中第i个字符,可以使用'A'+i-1得到。
例如:第5个字符为'E',亦即为:'A'+5-1
***********************************/
int main() {
char c1;
int n = 26; //设定塔的层数为26
int i, j;
for (i = 1; i <= n; i++) { //对塔每一层按照规律进行构造。
//首先进行输出空格的操作:对于第i行,字符前面的空格个数为n-i个。
for (j = 1; j <= n-i; j++)
printf(" ");
for (j = 1; j <= i; j++) { //按照规律1,输出第1~第i个大写字母。
c1 = j + 'A' - 1; //第j个大写字母为'A'+j-1
printf("%c", c1); //输出第j个大写字母
}
for (j = i-1;j >= 1; j--) {//按照规律1,输出第i-1~第1个大写字母,注意是倒序
c1 = 'A'+j-1;
printf("%c", c1);
}
printf("\n");//第i行输出结束,进行换行。
}
return 0;
}
日记
Description
看着林林色色的塔,你的心里有些许的安稳,在询问路人时你得知了,你正身处「卡卡利科村」,似乎帕雅也在那里?好久没有偷窥帕雅的日记了你喜欢偷窥帕雅日记一事已广为人知,帕雅特地在日记本上加了密。加密的方式很简单:对于一串字符串,如果其中有l,i,n,k,e这五个字母当中的任意一个,帕雅都会在这后面加上bt再加上原来的字母已加密,如love就会加密成lbtlovebte。下面给出帕雅日记的第一页内容,请你根据他的日记内容进行解密。
ibti lbtlovebte lbtlibtinbtnkbtkebtezbas jebte dosadnbtna
ovakbtkebtemibtijaxaszxdbtddbtddbtddbtddbtddbtd
注意上面内容为一行内容,没有任何换行,若网页显示多行只是文本显示宽度问题。
建议查看PDF。但这能拦得住你吗?时间紧迫,快解密吧!
Input
这是一道提交答案题,没有任何输入,只需要将问题的解使用输出语句输出即可。
Output
输出帕雅日记第一页解密后的内容。
Sample Input 1
这是一道提交答案题,没有任何输入,只需要将问题的解使用输出语句输出即可。
Sample Output 1
输出帕雅日记第一页解密后的内容。
- 思路:因为在l,i,n,k,e加密后,后面会产生bt+本身,但在解密时,这三个字母是什么并不重要,所以在解密时,每次跳过三个字母,即下标+4.
- 先输出当前数字再进行判断,不然会连续丢失4个字符
#include<iostream>
using namespace std;
#include<cstring>
int main()
{
char s[]="ibti lbtlovebte lbtlibtinbtnkbtkebtezbas jebte dosadnbtna ovakbtkebtemibtijaxaszxdbtddbtddbtddbtddbtddbtd";
int len=strlen(s);
for(int i=0; i<len; i++)
{
cout<<s[i];
if(s[i]=='l'||s[i]=='i'||s[i]=='n'||s[i]=='k'||s[i]=='e')
i+=3;
}
return 0;
}
//答案:"i love linkezbas je dosadna ovakemijaxaszxdbtddbtddbtddbtddbtddbtd"
神仙爱采药
Description
您是一个神仙,但您很喜欢采药。
您有一个神奇的背包,背包内有VV个格子。
您所在的空间内有一些药,每个药会占用 11 或 22 个格子。
每天可以进行一次如下操作:
采摘一个药材放入背包中,若此时背包中没有多余的格子来放入新的药材,可以先将背包中的若干药材扔出去,至于扔多少以及扔几个,全都由您决定。当然您也可以选择不去进行采摘操作。
每一天结束前,神奇背包中的每个药材都会产生一个药丸。
作为神仙,您知道每天您可以采摘的药材类型(即占用格子数目),注意,当天的药材如果不采摘,在第二天就会消失(当天药材仅限当天采摘)。
为了获得尽可能多的药丸,请您计算最终能获得的药丸数目最多是多少?
Input
给定一个整数 VV 表示背包的格子数量,接下来一行一个由1或2构成的字符串 ss 表示药占用体积的情况。
其中1表示该药占用体积为 11,2表示该药占用体积为 22。
|s|∣s∣表示天数
V\leq100000,|s|\leq 100000V≤100000,∣s∣≤100000
Output
最多的药丸数目。
Sample Input 1
3
212
Sample Output 1
5
Sample Input 2
5
12112
Sample Output 2
14
Sample Input 3
6
112212
Sample Output 3
18
Sample Input 4
3
21121
Sample Output 4
10
Hint
对于第四组样例:
第一天装入了体积为2的药,该天生产药丸数为1。
第二天装入了体积为1的药,该天生产药丸数为2。
第三天取出了体积为2的药,装入了体积为1的药,该天生产药丸数为2。
第四天未操作,生产药丸数为2。
第五天装入体积为1的药,该天生产药丸数为3
故 1+2+2+2+3=10 个
思路:
- 在背包没有装满时,无论药丸占空间为1还是2,每天都往里面装药丸。
- 在背包装满时,判断背包内是否有占空间为2的药丸,如果有,再分为两种情况1、(碰到体积为2的药丸,不操作,因为不能提高背包内药丸总数),2、(碰到体积为1的药丸,丢弃包内一个体积为2的药丸,装入体积为1的药丸,然后转到背包没有满的情况,实质上的改变是药丸数量不变,背包空间+1)。
- 背包满且药丸数量等于背包容量,说明此时是最优状态,接下来不需要任何操作,每天药丸数都增长容量的数字。
- 还有一个关键点就是,药丸总数可能会超过int的数据范围,当时并未注意到,应该使用long long数据类型。
#include<iostream>
using namespace std;
#include<cstring>
#include<stdio.h>
int main()
{
long long sum=0;
int v=0,bag=0,number=0;
char a[100005];
cin>>v;
getchar();
scanf("%s",&a);
int s=strlen(a);
for(int i=0;i<s;i++)
{
if(bag+int(a[i]-48)<=v)
{
bag+=int(a[i]-48);
number+=1;
sum+=number;
}
else if(bag==v&&number<v)
{
if(a[i]=='1')
{
bag-=1;
sum+=number;
}
if(a[i]=='2')
sum+=number;
}
else
sum+=number;
}
cout<<sum;
return 0;
}
奇怪的传输机增加了
Description
Input
输入仅一行,共三个整数 N,x,yN,x,y
Output
如果传输成功则输出YE5!,并输出传输的数据大小。
如果传输失败到则输出N0!,并输出一个整数表示在第几天失败,失败的时候仍有多少数据。
输出保留六位小数。
实际测试范围:
50000<=N<=200000,1<=x<=9 ,1≤y≤18
Sample Input 1
70000 20 140
Sample Output 1
N0!
9 1820.860641
Sample Input 2
70000 8 14
Sample Output 2
YE5!
3312.486449
Hint
出题人原话:请选手们按题面要求复制粘贴输出,看清楚是YE5。
- 思路:用户for循环控制天数就行了,注意点是最后一天也要计算,所以要取到等号。恢复的操作是在损耗之后,判断失败之前进行。
#include<iostream>
#include<stdio.h>
using namespace std;
int main()
{
int N,x,y;
cin>>N>>x>>y;
double a=2/3.0,limit=N/32.0,recover=N/2.0;
double n=N;
for(int i=1; i<=y; i++)
{
n=2/3.0*n;
if(i==x)
n+=N/2.0;
if(n<N/32.0)
{
cout<<"N0!"<<endl;
cout<<i<<' ';
printf("%.6f",n);
break;
}
if(i==y)
{
cout<<"YE5!"<<endl;
printf("%.6f",n);
}
}
return 0;
}
奇怪的小鸭子也增加了
Description
这题是个签到题。
有一个 A×B 的大澡盆,还有若干个a×b 的长方形小鸭子,澡盆里最少放几只鸭子后,便无法再向其中放入更多的鸭子?
鸭子很倔强,不能旋转成 b×a ,也不能重叠放置。
Input
四个整数,分别表示 A,B,a,b
1<=a<=A<=30000
1<=b<=B<=30000
Output
最少能放几只鸭子。
Sample Input 1
12 10 4 5
Sample Output 1
2
Sample Input 2
20 10 9 2
Sample Output 2
3
Hint
-
思路:刚开始产生了思维误区,使用1作为了最小误差,错误原因是,如果测试数据是边长为1的 正方形,过程中会计算出0并混乱。
-
选择0.000001为最小误差,所以使用a-0.000001来刻画出最大的间隙。以横向为例,开始处先空出(a-0.000001)距离,然后把剩下的A-(a-0.000001)进行分割,把每一个a+(a-0.000001)看成一个整体用[A-(a-0.000001)]/(2*a-0.000001),并用ceil函数向上取整。
-
向上取整的原因是,只要有一点小数出现,即使不能覆盖长度本身,但是由于左边开始出空出了巨大间隙,所以可以再放下一个。最后把两个维度上的数量相乘就是答案。
#include<iostream>
using namespace std;
#include<cmath>
int main()
{
int A,B,a,b;
cin>>A>>B>>a>>b;
double x=ceil((A-(a-0.000001))/(2*a-0.000001));
double y=ceil((B-(b-0.000001))/(2*b-0.000001));
cout<<x*y;
return 0;
}
关于哥俩好的数字这件事
Description
这题是个签到题。
数字 x,y 是个「哥俩好」数字,当且仅当数字 xx 的数位和与数字 yy 的数位和相同。
你需要找 n 个不同的正整数,使得这 n 个数字两两之间均为「哥俩好」数字且总和最小。
Input
一个整数 n , 1≤n≤5000
Output
最小的「哥俩好」数字总和。
Sample Input 1
5
Sample Output 1
110
Sample Input 2
2
Sample Output 2
11
Hint
对于样例2,我们可以选择1+10,故输出11
-
数据量较小,N最大为5000时,解也在60w以内,所以从1到60w枚举,计算每个数字的数位和f(n)。
-
使用桶的思想,开辟数组存放数位和为x的数字数,直到数组某个位置,即数位和一定的数字到达N,得到一个ans记录下来,直到别的数组位置数字量到达n,更新sum取min{ans,sum[x]}
#include<iostream>
using namespace std;
#include<cstring>
#include<cmath>
int DigitalBit (int x)
{
int total=0;
while(x)
{
total+=(x%10);
x/=10;
}
return total;
}
int n,cnt[500];
long long sum[500];
long long ans=1e18;
int main()
{
cin>>n;
for(int i=1; i<=600000; i++)
{
int x=DigitalBit(i);
if(cnt[x]<n)
{
cnt[x]++;
sum[x]+=i;
}
if(cnt[x]==n)
ans=min(ans,sum[x]);
}
cout<<ans;
return 0;
}
Chapter 5 Test 5 没有一遍听清的词组:
- give confirmmation : 证实;发出确认信
- good steering: 良好的操纵性能;方便操纵
- grasp keywords: 抓住重点
- grain pattern of timber: 木材纹理
- greyhound bus: 灰狗巴士(城市公交的一种)
- hard-hoofed animals: 硬蹄动物 hoof:蹄子;步行
- hall of residence:学生宿舍(英国)
- hands broken :指针坏了
- hands down :易如反掌
- heart attack :心脏病
- heat indicator : 热度指示
- high wind :大风