【渝北初2025级】寒假集训阶段性检测-3
1、车厢重组
题目
题目描述
在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转180度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列。他退休后,火车站决定将这一工作自动化,其中一项重要的工作是编一个程序,输入初始的车厢顺序,计算最少用多少步就能将车厢排序。
输入格式
有两行数据,第一行是车厢总数N(不大于10000),第二行是N个不同的数表示初始的车厢顺序。
输出格式
一个数据,是最少的旋转次数。
样例
样例输入
4
4 3 2 1
样例输出
6
解题思路
冒泡排序
求出每一个数要移动的次数
AC代码
#include<bits/stdc++.h>
using namespace std;
int a,x[10020],tot;
int main(){
cin>>a;
for(int i=1;i<=a;i++){
cin>>x[i];
}
for(int i=1;i<=a;i++){
for(int j=i-1;j>0;j--){
if(x[j]>x[i])tot++;//求移动次数
}
}
printf("%d",tot);
}
2、合理放球
题目
题目描述
n个各不相同球放入m个相同的盒子里,球全部放完后,要求最后没有空盒!求不同的放法总数。
输入格式
一行两个数n和m
n表示球数,m表示盒子数
(0<n≤20)(0≤m≤20)
输出格式
不同且合理的放法总数
样例
样例输入
3 2
样例输出
3
数据范围与提示
第二类stirling数
解题思路
AC代码
#include<bits/stdc++.h>
using namespace std;
int n,m;
long long a[50][50];
int main() {
scanf("%d %d",&n,&m);
for(int i=1;i<=30;i++) {
a[1][i]=a[i][i]=1;
}
for(int i=2;i<=m;i++) {
for(int j=i+1;j<=n;j++) {
a[i][j]=a[i-1][j-1]+a[i][j-1]*i;
}
}
printf("%lld",a[m][n]);
return 0;
}
3、卫星地图
题目
题目描述
一张矩形的卫星地图,有M行N列。行列中的0表示空地,1表示有建筑。有3种类型的建筑:
L型: 仅在一行上占据连续的若干个格子,长度至少为2,至多为N
C型:仅在一列上占据连续的若干个格子,长度至少为2,至多为M
S型:仅占据单个格子。
在同一行上或者同一列上可以出现多个建筑。
不同的建筑不会相邻,相邻是指上,下,左,右,以及左上,左下,右上,右下等八个方向。
求出不同类型的建筑的数量及长度。
输入格式
第1行:2个整数M和N
接下来M行,每行N个0或1,数字之间由空格分开
输出格式
第1行:先输出S,再输出1个整数表示S型建筑的数量,如果没有,则不输出。
接下来若干行,每行依次表示L型建筑的长度以及该长度的建筑数量,按长度递增的顺序输出,中间用一个空格分开,如果没有L型建筑,则不输出。
接下来若干行,每行依次表示C型建筑的长度以及该长度的建筑数量,按长度递增的顺序输出. 中间用一个空格分开,如果没有C型建筑,则不输出。
样例
样例输入
12 12
0 0 0 0 0 0 0 0 0 0 0 1
0 1 1 1 1 1 0 0 0 0 0 1
0 0 0 0 0 0 0 1 0 0 0 1
0 1 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0
0 1 0 1 1 1 1 1 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0
0 1 1 0 0 0 0 0 0 0 0 0
样例输出
S 1
L 2 1 //注意在L,2,1之间各有1个空格,下同。
L 5 1
L 6 1
C 3 2
C 4 1
数据范围与提示
1≤ M,N ≤ 1000
解题思路
直接从头到尾扫一遍,一个一个找出建筑物
AC代码
#include<bits/stdc++.h>
using namespace std;
int m,n;
int a[1020][1020];
int l[1020],c[1020],s;
bool b[1020][1020];
int k,f;
int main(){
cin>>m>>n;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j];
if(a[i][j]==1)b[i][j]=1;
}
}//读入
//printf("\n");
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
//printf("%d ",a[i][j]);
if(a[i][j]==1){//判断是否为一
if(a[i][j+1]==1&&b[i][j]==1){
int ans=2;
k=j+1;
b[i][k]=0;
while(a[i][k]==1){
k++;
ans++;
b[i][k]=0;
}
l[ans]++;
}//找L
else if(a[i+1][j]==1&&b[i][j]==1){
int ans=2;
f=i+1;
b[f][j]=0;
while(a[f][j]==1){
f++;
ans++;
b[f][j]=0;
}
c[ans-1]++;
}//找C
else if(b[i][j]==1) s++;//printf("%d %d ",i,j);//找S
}
}
//printf("\n");
}
if(s!=0) printf("S %d\n",s);
for(int i=2;i<=m;i++){
if(l[i]!=0)printf("L %d %d\n",i-1,l[i]);
}
for(int i=2;i<=n;i++){
if(c[i]!=0)printf("C %d %d\n",i,c[i]);
}//挨个输出
}
4、优美连接
题目
题目描述
给出n个2位整数(1≤n≤10),将这n个数拼成一个长2n位长整数:y=x1 x2 x3……x2n
然后进行计算: d=│x1-x2│+│x2-x3│+….+ │x2n-1-x2n│
问题:当n个数给出之后,找出一种拼接方法,使d最小。
例如:n=3 时,三个数分别为: 26,17,34
拼接方法有:
26 17 34 d=│2-6│+│6-1│+│1-7│+│7-3│+│3-4│=20
26 34 17 d=│2-6│+│6-3│+│3-4│+│4-1│+│1-7│=17
……
17 34 26 d=│1-7│+│7-3│+│3-4│+│4-2│+│2-6│=17
其中最小d为17
输入格式
第一行一个整数n,第二行n个整数
输出格式
一个整数,即最小的d
样例
样例输入:
3
26 17 34
样例输出:
17
AC代码
先咕着