试题
A:
卡片
本题总分:
5
分
【问题描述】
小蓝有很多数字卡片,每张卡片上都是数字
0
到
9
。
小蓝准备用这些卡片来拼一些数,他想从
1
开始拼出正整数,每拼一个,
就保存起来,卡片就不能用来拼其它数了。
小蓝想知道自己能从
1
拼到多少。
例如,当小蓝有
30
张卡片,其中
0
到
9
各
3
张,则小蓝可以拼出
1
到
10
,
但是拼
11
时卡片
1
已经只有一张了,不够拼出
11
。
现在小蓝手里有
0
到
9
的卡片各
2021
张,共
20210
张,请问小蓝可以从
1
拼到多少?
3182
提示:建议使用计算机编程解决问题。
【答案提交】
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N= 100000;
vector<int> card(10,2021);
int cnt(int n){
int k=n;
while(k>=10){
int s=k%10;
card[s]--;
if(card[s]<0){
return n;
}
k/=10;
}
card[k]--;
if(card[k]<0) return n;
return 0;
}
int main() {
int sum=1;
while(cnt(sum)==0){
sum++;
printf("%d\n",sum);
}
printf("%d",sum);
return 0;
}
试题
B:
直线
本题总分:
5
分
【问题描述】
在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上,
那么这些点中任意两点确定的直线是同一条。
给定平面上
2
×
3
个整点
{
(
x
,
y
)
|
0
≤
x
<
2
,
0
≤
y
<
3
,
x
∈
Z
,
y
∈
Z
}
,即横坐标
是
0
到
1
(
包含
0
和
1
)
之间的整数、纵坐标是
0
到
2
(
包含
0
和
2
)
之间的整数
的点。这些点一共确定了
11
条不同的直线。
给定平面上
20
×
21
个整点
{
(
x
,
y
)
|
0
≤
x
<
20
,
0
≤
y
<
21
,
x
∈
Z
,
y
∈
Z
}
,即横
坐标是
0
到
19
(
包含
0
和
19
)
之间的整数、纵坐标是
0
到
20
(
包含
0
和
20
)
之
间的整数的点。请问这些点一共确定了多少条不同的直线。
40257
【答案提交】
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100001;
struct point{
int x;
int y;
};
int main() {
vector<point> p;
int i,j,x=20,y=21;
for(i=0;i<x;i++){
for(j=0;j<y;j++){
p.push_back({i,j});
}
}
int len=p.size();
set<pair<double,double>> lines;
for(i=0;i<len;i++){
for(j=0;j<len;j++){
if(p[i].x!=p[j].x && p[i].y!=p[j].y){
double k=(p[j].y-p[i].y)*1.0/(p[j].x-p[i].x);
double b=(p[j].y*(p[j].x-p[i].x)-(p[j].y-p[i].y)*p[j].x)*1.0/(p[j].x-p[i].x);
lines.insert(pair<double,double>(k,b));
}
}
}
printf("%d",lines.size()+x+y);
return 0;
}
试题
C:
货物摆放
本题总分:
10
分
【问题描述】
小蓝有一个超大的仓库,可以摆放很多货物。
现在,小蓝有
n
箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝
规定了长、宽、高三个互相垂直的方向,每箱货物的边都必须严格平行于长、
宽、高。
小蓝希望所有的货物最终摆成一个大的立方体。即在长、宽、高的方向上
分别堆
L
、
W
、
H
的货物,满足
n
=
L
×
W
×
H
。
给定
n
,请问有多少种堆放货物的方案满足要求。
例如,当
n
= 4
时,有以下
6
种方案:
1
×
1
×
4
、
1
×
2
×
2
、
1
×
4
×
1
、
2
×
1
×
2
、
2
×
2
×
1
、
4
×
1
×
1
。
请问,当
n
= 2021041820210418
(注意有
16
位数字)时,总共有多少种
方案?
2430
提示:建议使用计算机编程解决问题。
【答案提交】
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100001;
const LL n= 2021041820210418;
int main() {
vector<LL> f;
int i,j,t=sqrt(n),ans=0;
for(i=1;i<=t;i++){
if(n%i==0){
f.push_back(i);
f.push_back(n/i);
}
}
int len=f.size();
for(i=0;i<len;i++){
for(j=0;j<len;j++){
if(n%(f[i]*f[j])==0){
ans++;
}
}
}
printf("%d",ans);
return 0;
}
试题
D:
路径
本题总分:
10
分
【问题描述】
小蓝学习了最短路径之后特别高兴,他定义了一个特别的图,希望找到图
中的最短路径。
小蓝的图由
2021
个结点组成,依次编号
1
至
2021
。
对于两个不同的结点
a
,
b
,如果
a
和
b
的差的绝对值大于
21
,则两个结点
之间没有边相连;如果
a
和
b
的差的绝对值小于等于
21
,则两个点之间有一条
长度为
a
和
b
的最小公倍数的无向边相连。
例如:结点
1
和结点
23
之间没有边相连;结点
3
和结点
24
之间有一条无
向边,长度为
24
;结点
15
和结点
25
之间有一条无向边,长度为
75
。
请计算,结点
1
和结点
2021
之间的最短路径长度是多少。
10266837
提示:建议使用计算机编程解决问题。
【答案提交】
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2021;
vector<int> dp(N+1,0);
int grc(int a,int b){
if(b==0) return a;
return grc(b,a%b);
}
int bns(int a,int b){
return (a*b)/grc(a,b);
}
int main() {
int i,j,k=21;
for(i=1;i<=22;i++){
dp[i]=i;
}
for(i=23;i<=N;i++){
int tmp=0,min=99999999;
for(j=i-k;j<i;j++){
tmp=dp[j]+bns(i,j);
min=tmp<min?tmp:min;
}
dp[i]=min;
}
printf("%d",dp[N]);
return 0;
}
未完待续!
续!!!
试题
F:
时间显示
时间限制
: 1.0s
内存限制
: 256.0MB
本题总分:
15
分
【问题描述】
小蓝要和朋友合作开发一个时间显示的网站。在服务器上,朋友已经获取
了当前的时间,用一个整数表示,值为从
1970
年
1
月
1
日
00:00:00
到当前时
刻经过的毫秒数。
现在,小蓝要在客户端显示出这个时间。小蓝不用显示出年月日,只需要
显示出时分秒即可,毫秒也不用显示,直接舍去即可。
给定一个用整数表示的时间,请将这个时间对应的时分秒输出。
【输入格式】
输入一行包含一个整数,表示时间。
【输出格式】
输出时分秒表示的当前时间,格式形如
HH:MM:SS
,其中
HH
表示时,值
为
0
到
23
,
MM
表示分,值为
0
到
59
,
SS
表示秒,值为
0
到
59
。时、分、秒
不足两位时补前导
0
。
【样例输入
1
】
46800999
【样例输出
1
】
13:00:00
【样例输入
2
】
1618708103123
【样例输出
2
】
01:08:23
【评测用例规模与约定】
对于所有评测用例,给定的时间为不超过
10^
18
的正整数。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int main() {
LL n;
scanf("%lld",&n);
n/=1000;
int h=(n/3600)%24,m=(n/60)%60,s=n%60;
int h1=h/10,h2=h%10,m1=m/10,m2=m%10,s1=s/10,s2=s%10;
printf("%d%d:%d%d:%d%d",h1,h2,m1,m2,s1,s2);
return 0;
}
试题 G: 砝码称重
时间限制
: 1.0s
内存限制
: 256.0MB
本题总分:
20
分
【问题描述】
你有一架天平和
N
个砝码,这
N
个砝码重量依次是
W
1
,
W
2
,
· · ·
,
W
N
。
请你计算一共可以称出多少种不同的重量?
注意砝码可以放在天平两边。
【输入格式】
输入的第一行包含一个整数
N
。
第二行包含
N
个整数:
W
1
,
W
2
,
W
3
,
· · ·
,
W
N
。
【输出格式】
输出一个整数代表答案。
【样例输入】
3
1 4 6
【样例输出】
10
【样例说明】
能称出的
10
种重量是:
1
、
2
、
3
、
4
、
5
、
6
、
7
、
9
、
10
、
11
。
1 = 1
;
2 = 6
−
4
(
天平一边放
6
,另一边放
4
)
;
3 = 4
−
1
;
4 = 4
;
5 = 6
−
1
;
6 = 6
;
7 = 1 + 6
;
9 = 4 + 6
−
1
;
10 = 4 + 6
;
11 = 1 + 4 + 6
。
【评测用例规模与约定】
对于
50
%
的评测用例,
1
≤
N
≤
15
。
对于所有评测用例,
1
≤
N
≤
100
,
N
个砝码总重不超过
100000
。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int dp[105][100005];
int abs(int x){
return x<0?(0-x):x;
}
int main() {
int N,i,j,ans=0,sum=0;
scanf("%d",&N);
int num[N+1];
for(i=0; i<N; i++) {
scanf("%d",&num[i]);
sum+=num[i];
}
dp[0][num[0]]=1;
for(i=1;i<N;i++){
dp[i][num[i]]=1;
for(j=1;j<=sum;j++){
if(dp[i-1][j]==1){
dp[i][j]=1;
dp[i][j+num[i]]=1;
dp[i][abs(j-num[i])]=1;
}
}
}
for(i=sum;i>0;i--){
if(dp[N-1][i]==1) ans++;
}
printf("%d",ans);
return 0;
}