目录
前言
本人大一新生,第一次参加比赛,写下一篇文章记录自己个人的一些代码和从零开始的ACMer生涯,如有错误和其他建议,烦请指出QwQ
00.A Cirno 的算数问题
题目描述
Cirno 是一个爱数学的孩子。
Cirno 最近学到了整数。她想到一个问题,假如给定一个整数 x,那么 9 和 x 正中间的整数是哪个数呢?Cirno算了一下,但是不知道自己算的对不对。
Cirno 遇到了麻烦,请你帮她实现一个程序吧!
输入
仅一行一个整数,x (≤x≤ )
输出
如果存在这个整数,输出这个数字。
否则输出Impossible
一些想法
简单分析后易得
若输入偶数 则输出Impossible
若输入奇数 则计算(x+9)\2即可
代码
#include <iostream>
using namespace std;
int main()
{
int x;
cin>>x;
if(x%2==0) //判断是否偶数
cout<<"Impossible"<<endl;
else
cout<<(x+9)/2<<endl;
return 0;
}
01.B Cirno 的扑克之囧
题目描述
Cirno 听闻,德州扑克是一款策略竞技游戏,牌技佼佼者,甚至可以年入百万。听罢,Cirno 心想怎么有这等好事,俺可不能错过啊,俺也要凭此大赚一笔。
于是 Cirno 找到知识丰富的 Patchouli,向她求教扑克规则。Patchouli 详细地介绍了扑克规则。Cirno 虽然很想学会这些,可惜她是个笨蛋,记忆力不行,没记住规则,甚至完全搞错了。
在她的认知里,规则被简化为,每人用 5 张牌的组合比拼大小,因记不住牌型,她模糊的印象里,「Full House」牌型是很大的(「Full House」就是 3 个数字一样的,加 2 个数字一样的牌型),幸好,这点没记错。她想到一个策略,只要抽到「Full House」牌型,管他三七二十九,直接全压All in!
,否则就弃牌Fold!
。这样肯定能赚很多钱!
Cirno 不够聪明, 看出这个牌型对她来说都太费劲了。因此,Cirno 找到懂编程的 Nitori,希望她实现程序,以便 Cirno 判断牌型。不巧的是,Nitori 最近正忙着修理坏掉的高达,没空编写这个程序。她将问题抛给了你,请你编写程序帮助 Cirno 吧!如果你实现了这个程序,Cirno 会奖励你一根冰棍!
输入
一行5个整数,以空格分隔,每个数为1到13的整数。
输出
如果5张牌的组合是「Full House」(三个数字一样,另外两个数字一样的),输出All in!
否则 输出Fold!
一些想法
在刚开始做题的时候还想如果输入的五个数字都一样应该All in还是Fold,后来在群里问了下发现好像一副扑克只有四张牌一样(挠头)
由于输入数字无序,所以我个人拿到题之后的第一想法是先将五个数排好序后再判断牌型
偷了点小懒就用了algorithm库的sort函数
代码
#include <iostream>
#include<algorithm>
using namespace std;
bool compare(int a,int b) //定义排序顺序
{
return a>b;
}
int main()
{
int a[5];
for(int i=0;i<5;i++)
{
cin>>a[i];
}
sort(a,a+5,compare); //排序
if((a[0]==a[1]&&a[1]==a[2]&&a[3]==a[4])||(a[4]==a[3]&&a[2]==a[3]&&a[1]==a[0])) //判断牌型
cout<<"All in!";
else
cout<<"Fold!";
return 0;
}
一些杂七杂八
此外在学长对比赛题目讲解时提出了另一个思路让正在洗澡的我顿悟了一下
可以检测输入数据的五个数字是否只有俩数,然后再进行判断
02.C matrix
题目描述
又是平常的一天,快要迟到的七海Nana7mi从出租车上跳下,还没来得及关车门就往公司大楼的门口飞奔而去。
刚到门口,七海突然发现大门上的密码锁好像和以前不太一样。她拿出手机,就看到了时守星沙在QQ群里发的新公告:“为了防止无关人员闯入,从今天开始,公司门禁密码更换为2个矩阵的乘积。今天的2个矩阵如下...”
七海不知道什么是矩阵乘法,但她知道,如果她不能在上班时间之前算出来,她一定会被某个小学男生同事狠狠地嘲笑的!她知道你的编程水平高超,于是她找到了你,希望你能够帮助她解决问题。
如果你不了解什么是矩阵乘法,以下是矩阵乘法的描述:
n × m 阶的矩阵A乘以m × k阶的矩阵B得到的矩阵C是n×k阶的,且C[i] [j] = A[i] [0]×B[0] [j] + A[i] [1] xB[1] [j]······A[i] [m-1]× B[m-1] [j] (C[i] [j]表示C矩阵中第i行第j列元素)。
输入
第一行为 n,m,k,表示 A 矩阵是 n行 m列,B 矩阵是 m行 k列,n,m,k 均小于 100。
然后先后输入 A 和 B 两个矩阵,A 矩阵 n行 m列,B矩阵 m行 k列,矩阵中每个元素的绝对值不会大于 1000。
输出
输出矩阵 C,一共 n行,每行 k个整数,整数之间以一个空格分开。
一些想法
看到这个题目之后让数学烂到家的我觉得十分哈人,决定放弃自己脆鲨的身份,但是细看题目的话数学不太好的话好像也没啥关系
基本思路就是造三个二维数组,输入A和B两个数组,用题中给出的公式算出C
代码
#include <iostream>
using namespace std;
int main()
{
int n,m,k;
int i,j,l;
cin>>n>>m>>k;
int a[n+1][m+1]={0},b[m+1][k+1]={0},c[n+1][k+1]={0}; //初始化数组
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
cin>>a[i][j]; //输入A数组
for(i=1;i<=m;i++)
for(j=1;j<=k;j++)
cin>>b[i][j]; //输入B数组
for(i=1;i<=n;i++)
for(j=1;j<=k;j++)
for(l=1;l<=m;l++)
c[i][j]+=a[i][l]*b[l][j]; //计算C数组
for(i=1;i<=n;i++)
{
for(j=1;j<=k;j++)
cout<<c[i][j]<<" "; //输出C数组
cout<<endl;
}
return 0;
}
03.D L学姐的数字
题目描述
何以解忧?唯有暴富!
L 学姐迫切地想要拥有大量的财富(发财),所以她对数字 8 (发)有着超乎寻常的热爱,所以她想找到很多很多满足每个数位上数字之和为 8 的倍数的数字,但是 L 学姐还有很多课业需要完成,没有闲暇时间做这些事情。于是她把这个任务交给了你,而你的任务非常简单:找到在区间 [1,n] 里满足上述条件的数字的个数。
输入
共 t+1 行。
第一行为一个数字 t,表示询问的个数。
接下来 t 行,每行为一个数字 n,表示询问区间的右边界。
输出
共 t 行。
每行一个数字,表示区间 [1,n] 里满足上述条件的数字的个数。
数据范围
n≤1×,t≤1×
一些想法
写一个大循环,用来多次找数字和输出个数,循环次数为t
找数字阶段,由于题中所给n的范围小于等于10^3,且n=1000的时候不符合条件,所以n最大是一共三位数,于是可以把[1,n]内的数字的每个位上的数字提取出来后相加判断是否等于8即可
我也想要暴富啊(悲)
代码
#include <iostream>
using namespace std;
int main()
{
int t,n;
cin>>t;
int a,b,c,d;
for(int i=0;i<t;i++)
{
cin>>n;
int num = 0;
for (int j=1;j<=n;j++)
{
a=j/100;
b=j%100/10;
c=j%10;
d=a+b+c; //提取数字后相加
if (d%8==0)
num++;
}
cout<<num<<endl;
}
return 0;
}
04.E 群主的深渊竞速赛
题目描述
国庆假期期间,群主在寝室感到异常无聊,于是和室友一起玩起了原神这款游戏。在这款游戏中有一个副本叫深渊,群主和室友五人约定他们六人分为两队,比赛通关速度。第一名完美通过深渊的人记 6 分,第二名通过的人记 5 分,以此类推,第六名得 1 分。最终比拼哪队总分更高。
聪明的群主好奇自己的队伍在某一局游戏中是否能得到某个总分,如果可以,有多少种排名情况可以达成该总分?
输入
第一行一个正整数 n,表示猜想的总分。
输出
如果可以达成,输出一个正整数 x,代表有多少种排名情况。
如果不能达成,输出No
。
数据范围
0≤n≤1000
一些想法
比赛写到这的时候有点急,一看数好像不多就决定暴力打表
学长讲题的时候提供了做法
将三个数相加后对应的数组自增,枚举出所有情况,最后根据输入的值输出相应数组元素
代码1(打表)
#include<iostream>
using namespace std;
int main()
{
int a;
cin>>a;
if ((a == 15) || (a == 14) || (a == 6) || (a == 7))
{
cout << "1" << endl;
}
else if ((a == 13) || (a == 8))
{
cout << "2" << endl;
}
else if ((a == 12) || (a == 11) || (a == 10) || (a == 9))
{
cout << "3" << endl;
}
else
cout << "No" << endl;
return 0;
}
代码2
#include<iostream>
using namespace std;
int a[1010];
int main()
{
for (int i = 1; i <= 6; ++i)
for (int j = i + 1; j <= 6; ++j)
for (int k = j + 1; k <= 6; ++k)
a[i + j + k]++; //枚举
int x;
cin>>x;
if(a[x]) //判断能否得出此分数
cout<<a[x];
else
cout<<"No";
return 0;
}
05.F L学姐的约定
题目描述
L 学姐带着计算机学术交流协会的成员约定好去参加迎新活动。
但是由于国庆放假,有部分成员想出去外面的大世界逛一逛,转一转,就直接放了L 学姐鸽子,所以到了约定的日子,只来了一部分人,
L 学姐要统计一下实际到的人数(不算L 学姐本人),于是 L 学姐开始了操作:她先让所有成员按照 3 人一排站好,结果剩下 x 个人;她又让所有成员按照 5 人一排站好,结果剩下 y 个人;她最后让 7 人一排站好,结果又剩 z 个人。此时 L 学姐说:好的,我已经知道实际到达多少人了!
问:实际来的人数是多少???
输入
一行三个数,分别表示 x,y,z。
输出
一个数,表示到的总人数(不包括L 学姐本人)如果有多种情况输出最小数。
数据范围
0≤x≤2,0≤y≤4,0≤z≤6
一些想法
经典的韩信点兵问题捏,由于数据范围不大可以枚举,也可以用中国剩余定理来解决
代码(枚举)
#include <iostream>
using namespace std;
int main()
{
int a, b, c;
cin>>a>>b>>c;
for(int i=0;;i++)
{
if(i%3==a&&i%5==b&&i%7==c)
{
cout<<i;
break;
}
}
return 0;
}
代码(中国剩余定理)
#include <iostream>
using namespace std;
int main()
{
int a,b,c;
cin>>a>>b>>c;
int result;
result=(70*a+21*b+15*c)%(3*5*7);
cout<<result;
return 0;
}
06.G L学姐的粉丝会密码
题目描述
很多 L 学姐的粉丝都想一睹 L 学姐的芳容。
L 学姐为了满足粉丝们的要求,决定召开一场粉丝见面会。但是她不想让一些可能会来砸场子的人来到现场拆台,所以她决定在招新群里不发出信息明确的原始文字(明文),而是发出通过密钥加密后的文字(加密规则详见注释),以使得那些想砸场子的人无从得知具体消息。不过,L 学姐为了她的粉丝们能够顺利得知准确消息,决定将密钥发给粉丝们。这样就只需要通过密钥,就可以将密文反推回明文了。
可惜,天有不测风云,想要砸场子的 S 学姐还是得知了密钥的具体内容,但她懒得做这么简单的事,于是便将破解明文的事情交给了你,而你的任务非常简单:通过给定的密文 C 和密钥 k 还原出明文 M。
输入
共 2 行。
第一行为一个字母,表示密钥 k,其为小写英文字母。
第二行为一个字符串,表示经加密后的密文,长度不超过 1×,其中仅包含小写英文字母。
输出
一个字符串,表示输入密钥和密文所对应的明文。
一些想法
明文:解密后的文字
密文:解密前的文字
表中第一行为密钥,第一列为明文,将密钥与密文对应后得出明文,不难发现密文经过一定偏移后得到明文
已知a的ASCII码为97,我们可以先把a-z变成0-26计算,防止超出ASCII码范围所以%26之后加97得到对应明文
代码
#include <iostream>
#include <string>
using namespace std;
int main()
{
char a;
string str;
cin>>a;
cin>>str;
for(int i=0;i<str.size();i++)
str[i]=((str[i]-97)+26-(a-97))%26+97;
cout<<str;
return 0;
}
07.H L学姐打水问题
题目描述
假设河水在 y=0 这条线上,L 学姐家住在西边的 A 点 (xa,ya),L 学姐从家出发到河边,然后前往东边的 B点 (xb,yb),再从 B 点出发到河边后,再前往最东边的 C 点 (xc,yc)结束。请你算出打水送水路线的最短路线长度。
请你输出一行答案,即最短路线的长度,结果精确到两位小数。
输入
输入 1 行,共 6 个整数,分别为 xa, ya, xb, yb, xc, yc,表示 `A`, `B`, `C`三个点的坐标
输出
请你输出一行答案,表示最短路线的长度,结果精确到两位小数。
一些想法
初中知识的将军饮马求两点间距离问题,不过要注意变量的数值范围!!
代码
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
double xa, xb, xc, ya, yb, yc;
cin >> xa >> ya >> xb >> yb >> xc >> yc;
double answer1, answer2;
answer1 = (xb-xa)*(xb-xa)+(ya+yb)*(ya+yb);
answer2 = (xc-xb)*(xc-xb)+(yb+yc)*(yb+yc);
printf("%.2lf", sqrt(answer1)+sqrt(answer2));
return 0;
}
总结
题目难度总体上来说还是很简单的,同时也发现了个人的一些不足,如变量的数值范围混淆,有些思路过于离谱和复杂,还有心态等方面的问题,比心中预想的成绩还是差了一点的,继续加油!