期末加油冲!记录一下做过的题目(๑′ᴗ‵๑)
阶乘末尾0的个数
输入格式:
输入有若干行。第一行上有一个整数m,指明接下来的数字的个数。然后是m行,每一行包含一个确定的正整数n,1<=n<=1000000000。
输出格式:
对输入行中的每一个数据n,输出一行,其内容是n!中末尾0的个数。
int trailingZeroes(int n){
int cnt=0;
if(n<5) return 0; //n<5阶乘末尾没有0!
while(n){ //需要注意这个循环的终止条件
cnt+=(n/=5); //每5就加一个0
}
return cnt;
}
螺旋方阵
输入格式:
输入在一行中给出一个正整数N(<10)。
输出格式:
输出N×N的螺旋方阵。每行N个数字,每个数字占3位。
#include<iostream>
const int N=10;
int main(){
int n;
int arr[N][N]={0};
scanf("%d",&n);
arr[0][0]=1; //最左上角填1
int total=n*n; //总共可以填进去的个数
int x=0,y=0,c=1; //c代表当前填的数字
while(c!=total) { //终止条件
//!ans[][]表示当前位置是否被填入
while(y+1<n&&!arr[x][y+1]) //从左向右
arr[x][++y]=++c;
while(x+1<n&&!arr[x+1][y]) //从上到下
arr[++x][y]=++c;
while(y-1>=0&&!arr[x][y-1]) //从右向左 注意这里要取到0!
arr[x][--y]=++c;
while(x-1>=0&&!arr[x-1][y]) //从下到上
arr[--x][y]=++c;
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
printf("%3d",arr[i][j]);
}
printf("\n");
}
}
找第k小的数
输入格式:
输入有两行: 第一行是n和k,0<k<=n<=10000 第二行是n个整数
输出格式:
输出第k小的数
/*据a[left]~a[right]中的某个元素x(如a[left])
对a[left]~a[right]进行划分,划分后的x所在位置的左段全小于等于x,右段全大于等于x,
同时利用x所在的位置还可以计算出x是这批数据按升非降序排列的第几个数。*/
int partition(int a[],int left,int right){
int temp=a[left]; //哨兵
while(left<right){ //终止条件
while(left<right&&a[right]>=temp){
right--;
}
a[left]=a[right];
while(left<right&&a[left]<=temp){ //要加上left<right 要取等号
left++;
}
a[right]=a[left];
}
a[left]=temp;
return left;
}
//通过调用partition函数获得划分点,判断划分点是否第k小,若不是,递归调用find函数继续在左段或右段查找。
int find(int a[],int left,int right,int k){
int p=partition(a,left,right);
if(p<k-1){ //划分点p小于k,往右
return find(a,p+1,right,k);
}
else if(p>k-1){ //划分点大于k,往左
return find(a,left,p-1,k);
}
else{
printf("%d",a[k-1]);
}
return 0;
}
int main(){
int n,k,a[1000];
scanf("%d %d",&n,&k);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
find(a,0,n-1,k);
return 0;
}
一、循环日程赛
【问题描述】设有n=2k个选手要进行网球循环赛,要求设计一个满足以下要求的比赛日程表:
(1)每个选手必须与其他n-1个选手各赛一次;
(2)每个选手一天只能赛一次;
(3)循环赛在n-1天之内结束。
int main(){
int Table[M][M];
int k,total;
scanf("%d",&k);
total=1<<k; //n=2^k;
//printf("%d",total);
int n=2; //n=2为初始
int i,j,m,tmp;
Table[1][1]=1; //初始化表格
Table[1][2]=2;
Table[2][1]=2;
Table[2][2]=1;
for(m=1;m<=k;m++){
tmp=n; //要放到循环里面 而且是tmp=nnnnn!!!
n*=2; //放到循环里面
for(i=1+tmp;i<=n;i++) //左下角
for(j=1;j<=tmp;j++)
Table[i][j]=Table[i-tmp][j]+tmp;
for(i=1;i<=tmp;i++) // 右上角 = 左下角
for(j=1+tmp;j<=n;j++)
Table[i][j]=Table[i+tmp][j-tmp]; //这里注意是Table[i+tmp][j-tmp]
for(i=tmp+1;i<=n;i++) //右下角 = 左上角
for(j=tmp+1;j<=n;j++)
Table[i][j]=Table[i-tmp][j-tmp];
}
for(int i=1;i<=total;i++){
for(int j=1;j<=total;j++){
printf("%3d",Table[i][j]);
}
printf("\n");
}
}
本文分享了三个有趣的算法题解析:计算阶乘末尾0的个数,生成螺旋方阵,以及寻找数组中第k小的数。文章详细介绍了算法原理和实现代码,适合算法初学者和竞赛选手参考。
307

被折叠的 条评论
为什么被折叠?



