2021年ZZUSOFT新生赛(第一场)题解
Posted 行码棋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021年ZZUSOFT新生赛(第一场)题解相关的知识,希望对你有一定的参考价值。
2021年ZZUSOFT新生赛(第一场)题解
题目链接
注意:数据类型范围,题目中有很多体现
A
直接输出对应的的ASCII码
'A' + 0 代表'A'
'A' + 1 代表'B'
#include<stdio.h>
#include<math.h>
int main()
{
for(int i=1;i<=26;i++)
{
int x;
scanf("%d",&x);
printf("%c",'A'+x-1);
}
return 0;
}
B
二进制转化为十进制
- 方法一:可以将相同的因子
2
提出来,最后化为下面的式子。
#include<stdio.h>
#include<string.h>
char s[100];
int main()
{
long long sum = 0;
scanf("%s",s);
int len = strlen(s);
for(int i=0;i<len;i++)
sum = sum * 2 + s[i]-'0';
printf("%lld\\n",sum);
}
- 方法二:从最低位开始按照二进制的定义转化为十进制
#include<stdio.h>
#include<string.h>
char s[66];
int main()
{
long long res = 0;
scanf("%s",s);
int len = strlen(s);
long long x = 1;
for(int i=len-1;i>=0;i--,x *= 2)
res += (s[i]=='1') * x;
printf("%lld\\n",res);
return 0;
}
C
剪刀石头布,列举所有情况。为简化程序,只取第一个字母进行比较。
#include<stdio.h>
#include<string.h>
char a[10],b[10];
int main()
{
scanf("%s%s",a,b);
if((a[0]=='s' && b[0]=='s') ||
(a[0]=='r' && b[0]=='r') || (a[0]=='p' && b[0]=='p'))
printf("D\\n");
else if((a[0]=='s' && b[0]=='p')||
(a[0]=='r' && b[0]=='s')||(a[0]=='p'&& b[0]=='r'))
printf("L\\n");
else printf("S\\n");
}
D
特殊情况先单列出来,然后根据斜率公式求斜率k,进而求出b。
#include<stdio.h>
#include<string.h>
int main()
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if(x1 == x2)
{
printf("x=%.6lf\\n",x1);
return 0;
}
double k = ((double)y2-y1)/(x2-x1);
double b = y1-k*x1;
printf("%.6lf %.6lf\\n",k,b);
return 0;
}
E
直接对应输出即可
#include<stdio.h>
#include<string.h>
int main()
{
int n;
char s[10];
scanf("%d%s",&n,s);
if(s[n-1]=='s') printf("YES\\n");
else printf("NO\\n");
}
F
化简式子得 ∣ x + 1 ∣ |x+1| ∣x+1∣
不能直接计算 x 2 + 2 x + 1 x^2+2x+1 x2+2x+1,会爆数据范围
当x为int型 ,x*x也为int型,如果乘出来的结果大于int的范围,就会溢出
#include<stdio.h>
#include<math.h>
int main()
{
long long x;
scanf("%lld",&x);
//printf("%lld\\n",abs(x+1));
if(x<-1) printf("%lld\\n",-x-1);
else printf("%lld\\n",x+1);
return 0;
}
G
一个点从原点走到另一个点,分为两种情况:
-
走的半径大于两点之间的距离,只需要两步就可以走到目标点。这两部走的路径刚好是等腰三角形的两腰,而两点连接而成的线段为等腰三角形的底边
-
走的半径小于两点之间的距离,记两点之间的距离为
dis
,半径为r
则 d i s = k ∗ r + x dis = k*r + x dis=k∗r+x ,k为整数,x为某个数,满足 x < r x < r x<r。
如果
x
为0,结果自然为k
如果
x
不为0, 前面的整数倍的半径可以走k-1
步。后面的那个x
只需要结合前面整数倍半径的最后一步,就能走到终点(和第一种情况一样)第二种情况总结下来就是求
dis/r
的上取整
#include<stdio.h>
#include<math.h>
int main()
{
int r,x,y;
scanf("%d%d%d",&r,&x,&y);
double dis = sqrt((double)x*x+(double)y*y);
if(r>dis) printf("2\\n");
else printf("%d\\n",(int)ceil(dis/r));
return 0;
}
H
本题求直角边平行于行列所在的直线的直角三角形。
可以考虑从直角三角形的直角顶点入手。
直角顶点所在行的点可以组成直角三角形的一个点,所在列的点可以组成直角三角形的一个点,当前行可以选择点的数量为当前行的1
的点的个数减一,当前列可以选择的点的个数为当前行的1
的点的个数减一,故我们只需要统计每行(row[]
)每列(col[]
)有多少点即可。
然后循环遍历每个点,如果当前点为1,则对答案加上 ( r o w [ i ] − 1 ) ∗ ( c o l [ j ] − 1 ) (row[i]-1)*(col[j]-1) (row[i]−1)∗(col[j]−1),注意要除去本身
#include<stdio.h>
int g[1005][1005];
int row[1005],col[1005];
int n,m;
int main()
{
long long res = 0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&g[i][j]);
if(g[i][j]==1)
{
row[i] ++;
col[j] ++;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(g[i][j]==1)
res += (row[i]-1)*(col[j]-1);
}
printf("%lld\\n",res);
return 0;
}
以上是关于2021年ZZUSOFT新生赛(第一场)题解的主要内容,如果未能解决你的问题,请参考以下文章
2021-2022 北京化工大学程序设计新生赛 - 问题 N: 聪明的蚂蚁 - 题解