65.求n天后的日期 66.输出菱形 68.素数(更高效的方法)

65.求n天后的日期

作者: Turbo

时间限制: 2s

章节: 函数

问题描述

写一个函数,传入年月日,计算它的第二天,并返回该日期。由用户输入年月日和一个n值,使用前述函数,计算该日期加n天的日期为多少。

输入说明

输入year,month,day和n共4个正整数,以空格分隔。n的值不超过2000。

输出说明

输出计算得到的结果年月日共3个正整数,整数之间以一个空格分隔,行首与行尾无多余空格。

思路

一天一天的向后判断,省去判断所有天数时的复杂。

注意指针格式

#include <stdio.h>

void nexttime(int *year,int *month,int *day){
    int days[]={31,28,31,30,31,30,31,31,30,31,30,31};
    if((*year % 4 == 0 && *year % 100 != 0) || (*year % 400 == 0)){
        days[1]++;
    }
    if(*day+1>days[*month-1]){
        if(*month+1>12){
            (*year)++;
            *month=1;
        }else{
            (*month)++; 
        }
        *day=1;
    }else{
        (*day)++;
    }
}

int main(){
    int year,month,day;
    int n;
    scanf("%d %d %d %d",&year,&month,&day,&n);
    for(int i=0;i<n;i++){
        nexttime(&year,&month,&day);    
    }
    printf("%d %d %d",year,month,day);
    return 0;
}

66.菱形输出

作者: 孙辞海

时间限制: 1s

章节: 函数

问题描述(题目描述写的像大粪,,,)

明明这次又碰到问题了:

给定一个正整数N,明明的爸爸让他输出一个以Z开始的菱形,以后依次为Y,X…,

比如当N等于1的时候输出图形:

Z

当N等于2的时候,输出图形:(Y前没有空格,Z、X和W前一个空格)

  Z

Y X

 W

当N等于3的时候,输出图形(Z前两个空格,Y、X前一个空格,W前没有空格......):

   Z

 Y X

W   V

 U T

   S

明明发现当N很大的时候就不是很容易了,所以找到了你,希望你编写一个程序帮助他

明明的问题可以归结为:输入一个正整数N,输出一个以Z开始的菱形,以后依次为Y,X…。

请尝试定义函数,该函数的功能是输出以上图形的一行。

输入说明

你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据仅占一行,每行仅包括一个正整数n(1≤n≤7)。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。

输出说明

对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将这一组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组输出一个以Z开始的菱形,具体格式参照样例输出。每组运算结果与其后一组运算结果之间有一个空行,最后一组运算结果之后没有空行。 注:通常,显示屏为标准输出设备。

#include <stdio.h>

// 打印菱形中“宽度为 width”的一行(width = 1,2,...,n,...,2,1)
// current 指向当前字母(从 'Z' 开始递减)
void line(int width, int n, char *current) {
    // 计算前导空格数 = n - width
    int leading_spaces = n - width;
    for (int i = 0; i < leading_spaces; i++) {
        printf(" ");
    }

    if (width == 1) {
        // 只输出一个字母
        printf("%c", *current);
        (*current)--;
    } else {
        // 输出两个字母:左 + 中间空格 + 右
        char left = *current;
        (*current)--;
        char right = *current;
        (*current)--;

        printf("%c", left);
        // 中间空格数 = 2 * (width - 1) - 1 = 2*width - 3
        int inner_spaces = 2 * width - 3;
        for (int i = 0; i < inner_spaces; i++) {
            printf(" ");
        }
        printf("%c", right);
    }
}

int main() {
    int n;
    int k = 0;

    while (scanf("%d", &n) == 1) {
        if (k>0) {
            printf("\n"); // 组间空行
        }
        k++;

        char current = 'Z';

        // 上半部分(包括中间行)
        for (int width = 1; width <= n; width++) {
            line(width, n, &current);
            printf("\n");
        }

        // 下半部分(不包括中间行)
        for (int width = n - 1; width >= 1; width--) {
            line(width, n, &current);
            printf("\n");
        }
    }

    return 0;
}

69.素数

作者: frankhuhu

时间限制: 3s

章节: 函数

问题描述

明明的爸爸是一位数学家,明明受他爸爸的影响从小就喜欢数学,经常向他爸爸学习或请教数学问题。一天,明明问他爸爸什么是素数,明明的爸爸回答说:“首先,素数都是大于1的自然数;其次,素数是只能被1和其本身整除的数。例如‘3’这个数,它只能被1和3这两个整数整除,因此‘3’就是素数;但是‘4’就不是素数,因为4除了能被1和4整除外,还能被2整除,因此‘4’就不是一个素数。”明明对于爸爸的回答很满意,也很快明白了素数的定义。于是明明的爸爸就问明明:“明明,你现在知道了什么是素数,那我现在给你一个整数区间,你能告诉我在这个区间里,一共有多少个素数吗?” 例如:一个区间为[1,10],则在这个区间里一共有2、3、5、7,总共4个素数。 明明想了想,觉得这很简单,就说:“没问题。”于是明明爸爸就给了明明一个很大的区间,这下明明有点犯难了,由于区间太大,一个一个算过了会很花时间。聪明的明明想到了你,你总是乐于助人。明明想让你帮他写一个程序,用来计算在某一个整数区间内一共有多少个素数。 明明的问题可以归结为:给你一个整数区间,求出在这个区间里共有多少个素数。

输入说明

你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据,每组测试数据仅有一行,每组测试数据有两个正整数M,N(0 < M ≤ N ≤ 1000000),表示一个整数区间。每组测试数据与其后一组测试数据之间没有任何空行,第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。

输出说明

对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将每组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果为一个整数,即区间[M, N]内一共有多少个素数。每组运算结果单独形成一行数据,其行首和行尾都没有任何空格,每组运算结果与其后一组运算结果之间没有任何空行,第一组运算结果前面以及最后一组运算结果后面也都没有任何空行。 注:通常,显示屏为标准输出设备

更高效的素数判断
i * i <= n循环次数从 ~n 降到 ~√n(9999 → 100 次)
跳过偶数再减少一半循环
n < 2 统一判断更健壮

假设 两个因子都大于 √n,即:

a>n,b>na>n​,b>n​

那么相乘:

a×b>n×n=na×b>n​×n​=n

但这与 a×b=na×b=n 矛盾!

所以,不可能两个因子都大于 √n
⇒ 至少有一个因子 ≤ √n。


🧠 推论:找因子只需查到 √n

  • 如果 nn 是合数,它一定有一个小于等于 √n 的因子
  • 反过来:如果我们在 [2,⌊n⌋][2,⌊n​⌋] 范围内找不到任何因子,那么 nn 就不可能是合数 → 它是素数

跳过偶数是为了进一步提高素数判断的效率,这是基于一个非常简单的数学事实:


✅ 核心原因:除了 2,所有偶数都不是素数

  • 素数定义:大于 1 且只能被 1 和自身整除的正整数。
  • 所有 大于 2 的偶数都能被 2 整除 → 一定是合数

所以:

  • 如果 n == 2 → 是素数 ✅
  • 如果 n > 2 且 n 是偶数 → 直接返回“不是素数” ❌

🔍 在判断因子时,为什么可以跳过偶数?

当我们检查一个奇数 n(比如 97)是否为素数时:

  • 不可能被任何偶数整除
    因为:奇数 ÷ 偶数 = 非整数(余数至少为 1)

举例:97 ÷ 2 = 48.5 → 不整除
97 ÷ 4 = 24.25 → 不整除
97 ÷ 6 = 16.166… → 不整除

#include <stdio.h>
int is_sushu(int n){
    if(n<2){
        return 0;
    }
    if(n==2){
        return 1;
    }
    if(n%2==0){
        return 0;
    }
    for(int i=3;i*i<=n;i+=2){
        if(n%i==0){
            return 0;
        }
    }
    return 1;
}
int main (){
    int a,b;
    while(scanf("%d %d",&a,&b)>0){
        int count=0;
        for(int i=a;i<=b;i++){
            if(is_sushu(i)){
                count++;
            }
        }
        printf("%d\n",count);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值