洛谷--入门题 (1)

1.上学迟到

请添加图片描述

代码:(转)

#include<cstdio>
#include<cmath>

using namespace std;
int s, v;

int main()
{
	int min, hour;
	scanf("%d%d", &s, &v);
	min = ceilf(double(s) / v + 10);
	hour = 7 - min / 60;
	if (hour < 0)
		hour += 24;
	min %= 60;
	min = 60 - min;
	printf("%02d:%02d", hour, min);
	return 0;
}

笔记:

  1. 可以利用ceil函数向上取整:ceilf(double(s) / v + 10)
  2. 当小时和分钟小于两位时左边要补0,%02d表示设置宽度为2,位数不足则在左边补0。

2. ABC排序

请添加图片描述

我的代码:

#include <iostream>
#include <vector>
#include <cmath>
#include <cstring>
#include <iomanip>
using namespace std;
int main() {
    int a[3];
    string flag;
    for (int i = 0; i < 3; ++i) {
        cin>>a[i];
    }
    sort(a,a + 3);
    cin>>flag;
    if (flag == "ABC"){
        cout<<a[0]<<' '<<a[1]<<' '<<a[2]<<endl;
    }
    else if (flag == "ACB"){
        cout<<a[0]<<' '<<a[2]<<' '<<a[1]<<endl;
    }
    else if (flag == "BAC"){
        cout<<a[1]<<' '<<a[0]<<' '<<a[2]<<endl;
    }
    else if (flag == "BCA"){
        cout<<a[1]<<' '<<a[2]<<' '<<a[0]<<endl;
    }
    else if (flag == "CAB"){
        cout<<a[2]<<' '<<a[0]<<' '<<a[1]<<endl;
    }
    else if (flag == "CBA"){
        cout<<a[2]<<' '<<a[1]<<' '<<a[0]<<endl;
    }
}

笔记:

  1. 对于输入的三个数字的排序,可以使用c++自带的排序函数解决:sort(a,a + 3);,处理之后,a[0]则是最小的数字,升序排序。
  2. 题目要求根据输入的字母数序将数字输出,我没有想到好的办法,就直接使用if语句来判断输出了(简单粗暴),但是在学习了别人的代码之后发现,可以将字母以字符的形式输入,然后将其减去 ‘A’的ascii码 ,这样A、B、C分别对应了0、1、2,即分别对应了数组的三个数字。

别人的代码

#include <iostream>
#include <algorithm>           //算法头文件
using namespace std;

int main()
{
	int a[3],i;
	char x,y,z;
	cin>>a[0]>>a[1]>>a[2];
	sort(a,a+3);          //这里偷个懒,用C++自带的排序算法做的,要加算法头文件
	cin>>x>>y>>z;
	cout<<a[x-65]<<' '<<a[y-65]<<' '<<a[z-65]<<endl;
}

3.分类平均在这里插入图片描述

我的代码:

#include <iostream>
#include <vector>
#include <numeric>
#include <cmath>
#include <cstring>
#include <iomanip>
using namespace std;

int main() {
    int n,k;
    double a,b;
    cin>>n>>k;
    vector<int>A;
    vector<int>B;
    for (int i = 1; i <= n; ++i) {
        if (i % k == 0){
            A.push_back(i);
        }
        else B.push_back(i);
    }
    double sum_a = accumulate(A.begin(),A.end(),0);
    double sum_b = accumulate(B.begin(),B.end(),0);
    a = sum_a / A.size();
    b = sum_b / B.size();
    printf("%0.1f ",a);
    printf("%0.1f\n",b);
}

笔记📒:

  1. 这道题比较简单,只需要注意一个地方,就是算平均值的时候分子和分母的数据类型不能是整形(int)否则算出来的数字会强行转换为整形,小数点后就全为0了。
  2. 要计算vector内各个元素只和,可以使用accumulate函数注意要引入头文件:numeric,用法:sum = accumulate(B.begin(),B.end(),0)

4. 数字直角三角形

请添加图片描述

我的代码:

#include <iostream>
#include <iomanip>
using namespace std;
int main() {
    int n;
    cin>>n;
    int count = 1;
    for (int i = n; i >= 1; --i) {
        for (int j = 0; j < i; ++j) {
            cout<<setw(2)<<setfill('0')<<count;
            count++;
        }
        cout<<endl;
    }
}

笔记📒:

  1. 对于直角边长为n的三角形,每一行的数字从n到1递减,两层循环即可解决,外层循环为n次即输出n行,内层循环为输出数字的个数。
  2. 还有一个要注意的地方是不足两位的数字要补零,解决办法我参考了🔗链接

使用包含于头文件 iomanip 的:
setw()设置宽度、
setfill()设置填充字符

使用方法如下:

cout<<setw(2)<<setfill('0')<<count;

5.阶乘之和请添加图片描述

别人的代码:LJC00118

#include<bits/stdc++.h>//万能头文件
using namespace std;
int a[100000],n,i,y,xy[100000],s[100000];//s[0]和a[0]表示两个数组的长度
//s表示答案,a表示阶乘,先算出阶乘,放在a里,再把s和它相加,更新s
void add()//表示s=s+a
{
    int i;
    memset(xy,0,sizeof(xy));//xy为辅助数组,先将a+s放入xy,再将s更新为xy
    xy[0]=max(s[0],a[0]);//更长的为xy数组长度
    for (i=1;i<=xy[0];i++)
    {
        xy[i]+=s[i]+a[i];//将每一位相加
        xy[i+1]=xy[i]/10;//进位
        xy[i]%=10;//进位
     }
    while (xy[xy[0]+1]>0) //进位
        {
            xy[xy[0]+2]=xy[xy[0]+1]/10;
            xy[xy[0]+1]%=10;
            xy[0]++;
        }
    s[0]=xy[0];//长度也要更新
    for (i=1;i<=xy[0];i++) s[i]=xy[i];//将xy给s
}
int main()//愉快的开始了主程序
{
    cin>>n;
    a[0]=1;//将数组初值赋好
    a[1]=1;//这里一定要是1,不然算阶乘的时候一直为0
    s[0]=1;
    s[1]=0;
    for (y=1;y<=n;y++) //这里是高精度乘法
    {
        memset(xy,0,sizeof(xy));//xy为辅助数组,先将a+s放入xy,再将s更新为xy
        xy[0]=a[0];
        for (i=1;i<=a[0];i++)
        {
          xy[i]+=a[i]*y;//算阶乘
          xy[i+1]=xy[i]/10;//进位
          xy[i]%=10;
        }
        while (xy[xy[0]+1]>0)//进位 
        {
            xy[xy[0]+2]=xy[xy[0]+1]/10;
            xy[xy[0]+1]%=10;
            xy[0]++;
        }
        for (i=1;i<=xy[0];i++) a[i]=xy[i];//算出y!放入a内
        a[0]=xy[0];
        add();//进行高精度加法
    }
    for (i=s[0];i>=1;i--) cout<<s[i];//输出
    cout<<endl;//换行
    return 0;//愉快的结束了主程序
}

笔记:

  1. 这道题我的主要知识盲点是关于高精度的处理,b站的这个视频讲挺好的
  2. 这道题还是不太明白,以后再来看。

6.回文质数 Prime Palindromes

请添加图片描述

我的代码:

#include <iostream>
#include <vector>
#include <cmath>
using namespace std;

bool check(int x){
    int a1 = x;
    int a2 = 0;
    while(x){
        a2 = a2*10 + x%10;
        x /= 10;
    }
    return a1 == a2;
}

int main(){
    int a,b;
    int num;
    int flag;
    vector<int>res;
    cin>>a>>b;
    for (int i = a; i <= b; ++i) {
        if (i >= 1e7+100) break;
        if (check(i)){
            flag = 0;
            for (int j = 2; j <= sqrt(i); ++j) {
                if (i % j == 0){
                    flag = 1;
                    break;
                }
            }
            if (flag == 0){
                res.push_back(i);
            }
        }
    }
    for (int i = 0; i < res.size(); ++i) {
        cout<<res[i]<<endl;
    }
}

笔记📒:

  1. 题目提醒我们:

找出所有的回文数再判断它们是不是质数

一开始我是按照提示思考的,但是我感觉还是太复杂了,因为有a和b的限制,产生的回文数要在这范围之内,总觉得很困难,在参考了别人的代码之后发现先判断回文数更简单一些。

  1. 我用了一个函数来判断回文数:(参考自Frozen_Guardian
bool check(int x){
    int a1 = x;
    int a2 = 0;
    while(x){
        a2 = a2*10 + x%10;
        x /= 10;
    }
    return a1 == a2;
}

思路就是先把x保存在a1那里,然后将x的所有数字倒置,放到a2那里,最后将a1和a2进行比较。

  1. 这个题目还有一个难点在于判断回文数我们只需要用一个函数O(lgn)的时间就可以判断,但a和b的范围高达1e8,1e8*lgn最大能到1e9,评测机肯定是顶不住的。
    加了这行代码之后最后一个测试点就通过了:if (i >= 1e7) break;

7.最长连号

请添加图片描述

我的代码:

#include <iostream>
using namespace std;

int main()
{
    int n;
    long arr[10000];
    int max = 1;
    int count = 1;
    cin>>n;
    for (int i = 0; i < n; ++i) {
        cin>>arr[i];
    }
    for (int i = 0; i < n - 1; ++i) {
        if (arr[i + 1] == arr[i] + 1){
            count++;
        }
        else{
            if (count > max){
                max = count;
            }
            count = 1;
        }
    }
    cout<<max;
}

笔记:

  1. 感觉这道题还挺有意思的,我一开始想用函数递归解决这个问题,但是觉得应该可以用循环实现,原来真的可以。
  2. 写完代码之后发现最后一个测试点没有通过,一开始以为是数据溢出了,就把int改成了long,还是不行。在看了别人代码之后发现我的arr数组大小太小了,改成1000之后就AC了。
  3. 所以以后数组的大小尽量设大一点。

8.冰雹猜想

请添加图片描述

我的代码:

#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;

int main() {
    int n;
    vector<int>res;
    cin>>n;
    while (n != 1){
        res.push_back(n);
        if (n % 2 != 0){
            n *= 3;
            n++;
        }
        else{
            n /= 2;
        }
    }
    res.push_back(1);
    for (int i = res.size() - 1; i >= 0; --i) {
        cout<<res[i]<<" ";
    }
}

笔记📓:

  1. 遍历vector容器时,res.size()指的正是数组的最后一个,所以不需要减1。

9.珠心算测验

请添加图片描述

myCode💻:

#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
int main() {
    int n;
    int count = 0;
    int arr[1000];
    int flag[100000] = {0};
    cin>>n;
    for (int i = 0; i < n; ++i) {
        cin>>arr[i];
    }
    for (int i = 0; i < n - 1; ++i) {
        for (int j = i + 1; j < n; ++j) {
            for (int k = 0; k < n; ++k) {
                if (arr[i] + arr[j] == arr[k] && flag[arr[k]] == 0){
                    count++;
                    flag[arr[i] + arr[j]] = 1;
                }
            }
        }
    }
    cout<<count;
}

笔记📒:

  1. 一定要看清楚题目啊!请添加图片描述

    既然是问有多少个数,那么一个数就只能计数一次,所以如果一个数满足条件之后,就要将其标记,以防下次再将其计入。


10.Bovine Bones G

请添加图片描述

myCode💻:

#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
int main() {
    int n;
    int a,b,c;
    int max = -1;
    int res[1000] = {0};
    cin>>a>>b>>c;
    for (int i = 1; i <= a; ++i) {
        for (int j = 1; j <= b; ++j) {
            for (int k = 1; k <= c; ++k) {
                res[i+j+k]++;
            }
        }
    }
    for (int i = 3; i <= a + b + c; ++i) {
        if (res[i] > max){
            max = res[i];
        }
    }
    for (int i = 3; i <= a + b + c; ++i) {
        if (res[i] == max){
            cout<<i;
            return 0;
        }
    }
}

笔记📒:

  1. 这道题感觉比较简单,唯一要注意的地方是循环的初始值一定要根据题目来定,不能默认为0。比如这道题每个骰子的最小值是1,所以应该从1开始。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值