洛谷入门级题单刷题笔记【自用】

提示:自用刷题笔记记录,洛谷题单入门级刷题


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;
}

结束语

浅浅记录刷题的一些关键代码

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值