提示:自用刷题笔记记录,洛谷题单入门级刷题
文章目录
1.月落乌啼算钱(斐波那契数列)
long long a=1,b=1,c=0;///因为n<=48,所以大一点
int n,i;
int main()
{
cin>>n;
for (i=3;i<=n;i++)
{
c=a+b;
a=b;
b=c;
}
cout<<c<<".00";///".00"是为了符合题意.......
return 0;
}
2.数字反转
给定一个整数 N,请将该数各个位上数字反转得到一个新数。新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零。
如输入123输出321,输入-380输出-83
使用字符串进行存储然后进行反转,有一个样例不可通过,存在bug
#include <bits/stdc++.h>//万能库包
using namespace std;
int n=0,s=0;
int main(){
for(cin>>n;n!=0;n/=10)s=s*10+n%10;//低位末尾的0会被%10给吸收掉,所以自动省去末尾的0,输出的结果自然就没有其末尾的0
cout<<s;return 0;
}
3.质数口袋
他从 2开始,依次判断各个自然数是不是质数,如果是质数就会把这个数字装入口袋。
口袋的负载量就是口袋里的所有数字之和。
但是口袋的承重量有限,装的质数的和不能超过 L。给出 L,请问口袋里能装下几个质数?将这些质数从小往大输出,然后输出最多能装下的质数的个数
int prim(int num){//判断素数
if(num<=1)return -1;
int i;
for(i=2;i*i<=num;i++){
if(num%i==0)return -1;
}
return 1;
}
int main()
{
long long sum=0;
int i; int n;
int count=0;
cin>>n;
for(i=2;;i++){
if(prim(i)==1){//如果是质数就放入口袋
sum+=i;
if(sum>n)break;//没放入一次就进行判断是否大于了袋子承重
cout<<i<<endl;
count++;
}
}
cout<<count;
return 0;
}
4.阶乘之和
直接使用循环进行阶乘相加会超出位,故使用高精度乘积和高精度加法
#include<stdio.h>
int main()
{
int i,A[1005]={0},B[1005]={0},n,j;
scanf("%d", &n);
A[0]=B[0]=1;//初始化第一位,A为最终结果,B为阶乘结果
for (i=2;i<=n;i++){
for (j=0;j<100;j++)
B[j]*=i;//相乘得到阶乘结果
for (j=0;j<100;j++)//对阶乘结果进行进位处理
if (B[j]>9){
B[j+1] += B[j]/10;
B[j]%=10;
}
for (j=0;j<100;j++){//将每一个完成的阶乘相加得到A
A[j]+=B[j];
if (A[j]>9) {//对A进行进位处理
A[j+1] += A[j]/10;
A[j]%=10;
}
}
}
for (i=100;i>=0&&A[i]==0;i--);//将未使用的高位进行处理掉
for (j=i;j>=0;j--) printf("%d", A[j]);
return 0;
}
5. 津津的储蓄计划
他打算在每个星期一筹集 xx 元,星期二筹集x+k元,……,星期日筹集x+6k元,并连续筹集 52个星期。其中 x,k为正整数,并且满足1≤x≤100。
现在请你帮忙计算x,k为多少时,能刚好筹集n元。
如果有多个答案,输出x尽可能大,k尽可能小的。
int main(){
int n;
cin>>n;
int x,k;
for(k=1;;k++){//k在外层循环就会导致k尽可能小,x尽可能大
for(x=1;x<=100;x++){
if(364*x+1092*k==n){
cout<<x<<endl<<k;
return 0;
}}}
return 0;
}
6.最长连号
输入长度为 n 的一个正整数序列,要求输出序列中最长连号的长度。
连号指在序列中,从小到大的连续自然数。
已经输入给出数据个数,所以就以此做循环条件,每次输入一个数,判断是否为上一个数加一(连续自然数)。
1,如果是,则临时计数(c)加一,
2,如果不是(断了),则将临时计数(c)赋为最初的1。
在此期间若临时计数超过答案(ans),则把临时计数的值赋给答案(ans).最终每个数据都判断完成后输出答案(ans)
#include<iostream>
using namespace std;
int main(){
int ans=0;
int i,n,m,pre=-1,num;
cin>>n;
for(i=0;i<n;i++){
cin>>m;
if(m==pre+1)num++;
else num=1;
if(num>ans)ans=num;
pre=m;
}
cout<<ans;
return 0;
}
7.小鱼比可爱
输入一个数列,求出每一个数左边有多少个比这个数小的数
for(i=0;i<n;i++){
for(int j=0;j<=i;j++){
if(a[i]>a[j])num++;//只计数左边的
}
b[i]=num;
num=0;
}
for(i=0;i<n;i++)cout<<b[i]<<" ";
8.校门外的树
0到n的数轴上,以1为单位种树,输入x个区间,将这x个区间的树移走,要求输出最后剩余的总数。
此处利用数组进行标识树是否还在,只需要将区间内的数组相应赋值为0即可
for(i=0;i<n+1;i++)a[i]=1;
int sum=0;
int b,c;
for(i=0;i<m;i++){
cin>>b>>c;
for(int j=b;j<=c;j++)a[j]=0;
}
for(i=0;i<n+1;i++){
sum+=a[i];
}
9.工艺品制作
一个长宽高实体,给出x1y1z1,x2y2z2对角线进行切割,问剩下多少块小的立方体
可以使用三维数组进行判别
for(j=x1;j<=x2;j++)
for(k=y1;k<=y2;k++)
for(l=z1;l<=z2;l++)
V[j][k][l]=1;
for(i=1;i<=w;i++)
for(j=1;j<=x;j++)
for(k=1;k<=h;k++)
if(V[i][j][k]==0)sum++;
cout<<sum;
return 0;
}
10.神奇的幻方
当 N为奇数时,我们可以通过下方法构建一个幻方:
首先将 1写在第一行的中间。
之后,按如下方式从小到大依次填写每个数 K(K=2,3,⋯,N×N) :
若 (K-1)在第一行但不在最后一列,则将 K填在最后一行,(K−1) 所在列的右一列;
若 (K-1)在最后一列但不在第一行,则将 K 填在第一列, (K-1)(K−1) 所在行的上一行;
若 (K-1)在第一行最后一列,则将 KK 填在 (K-1) 的正下方;
若 (K-1) 既不在第一行,也不在最后一列,如果 (K-1)的右上方还未填数,则将 KK 填在 (K-1)的右上方,否则将 KK 填在 (K-1) 的正下方。
现给定 N ,请按上述方法构造 N×N 的幻方。
#include<cstdio>
using namespace std;
int n,a[40][40],x,y;
int main(){
scanf("%d",&n);
x=1,y=(n+1)/2;
for(int i=1;i<=n*n;i++){
a[x][y]=i;
if(!a[(x-2+n)%n+1][y%n+1]) x=(x-2+n)%n+1,y=y%n+1;
else x=x%n+1;//数学运算
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
printf("%d ",a[i][j]);
}
printf("\n");
}
}
11.梦中的统计
给出两个整数 M 和 N,求在序列[M,M+1,M+2,…,N−1,N] 中每一个数码出现了多少次。
for(i=a;i<=b;i++){
j=i;
while(j){
int temp=j%10;
ans[temp]++;//相应的数目对应的数组加1
j/=10;
}
}
12. 爱与愁的心痛
最近有 n 个不爽的事,每句话都有一个正整数刺痛值。爱与愁大神想知道连续 m 个刺痛值的和的最小值是多少
int n,m;
cin>>n>>m;
int i;
int a[n];
for(i=0;i<n;i++)cin>>a[i];
int min=999999999;int temp;
for(i=0;i<n-m+1;i++){
temp=0;
for(int j=i;j<i+m;j++){
temp+=a[j];
}
if(temp<min)min=temp;
}
13.珠心算测验
他随机生成一个正整数集合,集合中的数各不相同,然后要求学生回答:其中有多少个数,恰好等于集合中另外两个(不同的)数之和?
int a[n];
int b[20000]={0};
int i;
for(i=0;i<n;i++){ cin>>a[i]; }
int j,sum=0;
for(i=0;i<n-1;i++){
for(j=i+1;j<n;j++){//每两个进行和运算
b[a[i]+a[j]]=1;//将b数组相应下标为和的置1即可
}
}
for(i=0;i<n;i++){
if(b[a[i]]==1){//即表示和为输入数组里面的数置了1就表示刚好等于集合中另外两个数之和
sum+=b[a[i]];
}
}
cout<<sum;
14.Bovine Bones G
对于一个有S个面的骰子每个面上的数字是1,2,3,…,S。每个面(上的数字)出现的概率均等。贝茜希望找出在所有“三个面上的数字的和”中,哪个和的值出现的概率最大。
现在给出每个骰子的面数,需要求出哪个所有“三个面上的数字的和”出现得最频繁。如果有很多个和出现的概率相同,那么只需要输出最小的那个。
int a,b,c;
cin>>a>>b>>c;
int ans[90]={0};
int i,j,k;
for(i=1;i<=a;i++)//直接暴力
for(j=1;j<=b;j++)
for(k=1;k<=c;k++){
ans[i+j+k]++;//直接使用和的下标进行存储
}
int max=-1;
int point=-1;
for(i=0;i<90;i++){
if(max<ans[i]){
max=ans[i];
point=i;
}
}
cout<<point;//输出的是出现最多的和的值
15.开灯
在刚开始的时候,所有的灯都是关的。小明每次可以进行如下的操作:
指定两个数a,t(a为实数,t为正整数)。将编号为⌊a⌋,⌊2×a⌋,⌊3×a⌋,…,⌊t×a⌋ 的灯的开关各按一次。其中⌊k⌋ 表示实数 kk 的整数部分。
在小明进行了n次操作后,小明突然发现,这个时候只有一盏灯是开的,小明很想知道这盏灯的编号
使用数组的方法:
#include<iostream>
using namespace std;
int ans[2000001]={0};//0是关
int main(){
int n;
cin>>n;
int i,a;
int t;
double aa;
for(i=0;i<n;i++){
cin>>aa>>t;
double j;
for(j=1;j<=t;j++){//不能使用 for(j=aa;j<=aa*t;j=j+aa)会导致有时候最后一个无法进入判断,怀疑可能是精度最后一位导致出错无法进行比较?
a=(int)j*aa;
if(ans[a]==1)ans[a]=0;//进行按动开关
else ans[a]=1;
}
}
for(i=1;;i++){
if(ans[i]==1)break;
}
cout<<i;
return 0;
}
16.蛇形方阵
给出一个不大于9的正整数 nn,输出n×n 的蛇形方阵。
从左上角填上1开始,顺时针方向依次填入数字,如同样例所示。注意每个数字有都会占用3个字符,前面使用空格补齐
int a[9][9]={0};
int main(){
int n,k=1;
cin>>n;
int x=0,y=-1;//从原点坐标开始进行存储数字
while(k<=n*n){//注意边界的限制
while(y<n-1&&!a[x][y+1])a[x][++y]=k++;//先往右边走
while(x<n-1&&!a[x+1][y])a[++x][y]=k++;//再往下边走
while(y>0&&!a[x][y-1])a[x][--y]=k++;//往左边走
while(x>0&&!a[x-1][y])a[--x][y]=k++;//往上边走
}
for(int i=0;i<n;i++)//打印输出
{
for(int j=0;j<n;j++){
printf("%3d",a[i][j]);
//使用printf输出三个字符的格式%3d
}
cout<<endl; }
return 0; }
17.
#include<iostream>
using namespace std;
int huo[5][5] ={{0,0,1,0,0},{0,1,1,1,0},{1,1,1,1,1},{0,1,1,1,0},{0,0,1,0,0}};
int ys[5][5] ={{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1}};
int main(){
int n,m,k;
cin>>n>>m>>k;
int map[n][n];
int shaox=0,shaoy=0;
int i,j,t;
for(int i=0;i<n;i++){//一定要进行初始化
for(j=0;j<n;j++){
map[i][j]=0;
}
}
int x,y;
for(i=0;i<m;i++){//火把
cin>>x>>y;
x--;
y--;
shaox=0;
for(int q=x-2;q<=x+2;q++,shaox++){
for(int w=y-2;w<=y+2;w++,shaoy++){
if(q>=0&&q<n&&w>=0&&w<n){
if(huo[shaox][shaoy]==1)map[q][w]=1;
}
}
shaoy=0;
}
}
for(i=0;i<k;i++){//萤火
cin>>x>>y;
x--;
y--;
shaox=0;
for(int q=x-2;q<=x+2;q++,shaox++){
for(int w=y-2;w<=y+2;w++,shaoy++){
if(q>=0&&q<n&&w>=0&&w<n){
if(ys[shaox][shaoy]==1)map[q][w]=1;
}
}
shaoy=0;
}
}
int result=0;
for(int i=0;i<n;i++){
for(j=0;j<n;j++){//0为未被燃烧的
if(map[i][j]==0)result++;
}
}
cout<<result;
return 0;
}
18.压缩技术
7 3 1 6 1 6 4 3 1 6 1 6 1 3 7 (第一个数是N ,其余各位表示交替表示0和1 的个数,压缩码保证N×N= 交替的各位数之和)输出01组成的数组
int main(){
int n;
cin>>n;
int a[n][n];
int i,j,k,l;
int num=0,sum=0;
int x;
int b[400];
int len=0;
for(i=0;;i++){
cin>>x;
sum+=x;
b[i]=x;
len++;//记录每个0 or 1的个数
if(sum==n*n)break;//当相等则证明输入个数结束
}
int flag=0;//交换的符号0 1
for(i=0;i<len;i++){
for(j=0;j<b[i];j++){
cout<<flag;
num++;
if(num==n){//进行换行
cout<<endl;
num=0;
}
}
if(flag==0)flag=1;
else flag=0;
}
19.压缩技术续集
从给的点集数组得到一行数字 n和01交替的连续数字
#include <stdio.h>
#include <string.h>
int main()
{
int i,n,num,sum;
char text[40000],str[200];//text:最终字符串,str:缓冲字符串
scanf("%s",str);
n=strlen(str);//输入第一个字符串,存入缓冲字符串,并计算n值
strcat(text,str);//将str连接到text后,其实也可以用strcpy的,用处相同
for(i=2;i<=n;i++)//因为已经连接第一个了,因此循环从第二行字符开始
{
scanf("%s",str);
strcat(text,str);//输入并连接
}
printf("%d ",n);//输出n值,记住在每个输出后带上空格
for(i=0,sum=0,num='0';i<=strlen(text);i++)//从text[i]开始循环
if(num==text[i])判断这个字符是否与上一个字符相等(第一个字符与‘0’做判断)
sum++;//如果相等,sum加一
else
{
num=text[i];
printf("%d ",sum);//反之,输出sum值(带空格),并初始化num与text
sum=1;
}
return 0;
}
结束语
浅浅记录刷题的一些关键代码