蓝桥杯省赛备战笔记——(一)基础 + 字符串和日期

视频在B站被和谐了。。。。幸好提前下载了。。。。有需要的可以私信我

【晚一阵子吧,疫情还比较严重,道全封了,还在农村,没有网】

一、基础部分杂记

在竞赛中,我们认为计算机一秒能执行  5 * 10 ^ 8 次计算,如果题目给出的时间限制是 1 s ,那么你选择的算法 执行的计算次数量应该在 10^ 8 量级,才能解决这类问题

 例题: 求循环节长度

 

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;
int f(int n,int m){
    n = n % m;   //求 小数的循环节,这步消除了整数部分的数字
    vector<int> v;
    for(;;){
        v.push_back(n);
        n *= 10;
        n = n % m;
        if(n == 0) return 0;
        if(find(v.begin(),v.end(),n) != v.end()){   //vector 中 从前往后找n,如果找到了n,返回的是n在 vector 中的位置
            //在下方填入代码                          如果没有找到,则返回 v.end() ,其值为空
            
        }
    }
}

int main(){
    int n,m;
    cin >> n >> m;
    cout << f(n,m) << endl;
    return 0;
}

插入的代码:

return (int) (v.end() - find(v.begin(),v.end(),n));

初次求模运算消除整数部分的数字,在之后的每次计算时,先n * 10,再n 取余m, 看余数是否出现过,如果余数出现过,就认为“开始了循环"

也可以看看这篇博客

https://blog.csdn.net/zm15229608646/article/details/79551977

 二、字符串

 例题:

#include<iostream>
#include<string>
using namespace std;
int main(){
    int n;
     cin >> n;
     for(int i = 1;i <= n;i++){
        string space = string(/* 请在这里填写代码 */,' ');
        string ch = string(/* 请在这里填写代码 */,/* 请在这里填写代码 */);
        cout << space + ch << endl;
     }

    return 0;
}

C++有个特殊的构造方法,string xx = string( .....,.....);   前面填整数,后面填字符,表示该字符串由多少个该字符组成

        string space = string( n - i,' ');
        string ch = string(2 * i - 1 ,'A'+i-1);

例题

 

  

#include<stdio.h>
int main(){
    char c;
    c = getchar();
    if(c >= 'A' && c <= 'Z'){
        for(int i = 1;i <= c - 'A' + 1;i++){
            for(int j = 1; j <=c - 'A'  + 1 - i;j++){
                printf(" ");
            }
            for(int j = 1;j <= i;j++){
                printf("%c",'A'+j-1);
            }
            for(int j = i - 1;j >= 1;j--){
                printf("%c",'A'+j-1);
            }
            printf("\n");
        }


    }else{

        for(int i = 1;i <= c - '1' + 1;i++){
            for(int j = 1; j <=c - '1'  + 1 - i;j++){
                printf(" ");
            }
            for(int j = 1;j <= i;j++){
                printf("%c",'1'+j-1);
            }
            for(int j = i - 1;j >= 1;j--){
                printf("%c",'1'+j-1);
            }
            printf("\n");
        }
    }
    return 0;
}

例题:造房子

 

 样例输出2中,再加一行“+-+-+-+-+”

#include<stdio.h>
int main(){
    int x,y;
    scanf("%d %d",&x,&y);
    for(int i = 0;i < x;i++){
        printf("+");
        for(int j = 0;j < y;j++){
            printf("-+");
        }
        printf("\n|");
        for(int j = 0;j < y;j++){
            printf("*|");
        }
        printf("\n");
    }
    printf("+");
    for(int j = 0;j < y;j++){
        printf("-+");
    }


    return 0;
}

 例题:

输入: 2

输出: ABA

#include<stdio.h>
#include<string.h>

char res[5000000];
int main(){
    int n;
    scanf("%d",&n);
    int len = 0;
    for(int i = 1;i <= n;i++){
        strcat(/* 插入代码 */,res);
        res[len] = 'A' + i - 1;
        len = strlen(res);

    }
    printf("%s\n",res);
    return 0;
}
strcat(res + len + 1, res );

例题:寻找字符串

 gets() 不会吃掉最后的换行,但由于对输入的长度没有限制,所有在C++11中因为不安全被放弃。比赛时勿用

 fgets() 会吃掉最后的换行

#include<stdio.h>
#include<string.h>
char s1[1005],s2[1005];
int main(){
    fgets(s1,1004,stdin);  //三个参数依次是,存入的字符串,最大长度,从哪里读入 【stdin为标准输入】 
    fgets(s2,1004,stdin);
    //fgets() 函数,遇到换行符截止读,但会读入换行符,所以在linux环境下,换行符为\n,windows环境中,换行符为 \r\n
    //所以,在求相关字符串长度时,灵活根据评测机的环境,-1 / -2
    int len1 = strlen(s1)-1,len2 = strlen(s2)-1;
    int ans = 0;
    for(int i = 0; i+ len2 - 1 < len1; i++){
        bool matched = true;
        for(int j = 0;j < len2;j++){
            if(s1[i + j] != s2[j]) {
                matched = false;
                break;
            }
        }
        if(matched)
            ans++;
    }
    printf("%d",ans);
    return 0;
}

 三、日期

 闰年的判断

int is_leap_year(int year){
    if(year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
        return 1;
    else
        return 0;
}

 每个月天数的判断

 一、三、五、七、八、十、腊,三十一天永不差。四、六、九、冬三十整,唯有二月二十八。逢到闰年加一日,如果不加就算差!

根据日期计算星期几———— 蔡基姆拉尔森计算公式

 例:如果是2004-1-10则换算成:2003-13-10来代入公式计算

 例题:生日

 

 

#include<iostream>
#include<string>
using namespace std;
int is_leap_year(int y){
    if(y % 400 == 0 || (y % 100 != 0 && y % 4 == 0))
        return 1;
    else
        return 0;
}
int whatday(int y,int m,int d){
    int ans = 0;
    for(int i = 1;i < y;i++){
        if(is_leap_year(i)){
            ans += 366 % 7;
            ans %= 7;    
        }else{
            ans += 365 % 7;
            ans %= 7;
        }  
    }
    for(int i = 1; i < m;i++){
        if(i == 1 || i == 3 || i == 5 || i == 7 ||i == 8 || i == 10 || i == 12){
            ans += 31 % 7;
            ans %= 7;
        } else if(i == 4 || i == 6 || i == 9 || i == 11){
            ans += 30 % 7;
            ans %= 7;
        }else if (i == 2){
            if(is_leap_year(y)){
                ans += 29 % 7;
                ans %= 7;
            }else{
                ans += 28 % 7;
                ans %= 7; 
            }
        }
    }
    ans += (d - 1) % 7;   //string数组,是从下标0开始,所以所有的计算,应该相应的 -1 操作
    ans %= 7;
    return ans;
}
string weekday[7] = {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
int main(){
    int y,m,d;
    cin >> y >> m >> d;
    cout << weekday[whatday(y,m,d)] << endl;
    return 0;
} 

 例题:恋爱纪念日

 

#include<stdio.h>
int day[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int main(){
    int y,m,d,k;
    scanf("%d%d%d%d",&y,&m,&d,&k);
    for(int i = 1;i <= k;i++){
        if(y % 400 == 0 || (y % 100 != 0 && y % 4 == 0)){
            day[2] = 29;
        }else{
            day[2] = 28;
        }
        d++;
        if(d == day[m] + 1){
            m++;
            d = 1;
        }
        if(m == 13){
            y++;
            m = 1;
        }
    }
    printf("%04d-%02d-%02d",y,m,d);   //%04d 4位,不足四位用0占位
    return 0;
}

 习题:节假日

简而言之,就是从前往后遍历,如果该天是 周六 or 周天 or 节假日,就 sum++  

具体题干可以看下这篇博客:

 https://www.cnblogs.com/ACPIE-liusiqi/p/8682905.html

代码:

#include<stdio.h>
int mm[10] = {1,5,10,10,10,12};
int dd[10] = {1,1,1,2,3,25};
int day[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
void nextday(int &y,int &m,int & d){
    d++;
    if(d == day[m] + 1){
        d = 1;
        m++;
    }
}
int main(){
    int y,w,m,d,sf,ans;
    scanf("%d",&y);
    for(int i = 6; i <= 9;i++){
        scanf("%d%d",&mm[i],&dd[i]);
    }
    scanf("%d",&w);
    if((y % 400 == 0 || (y % 100 != 0 && y % 4 == 0))){
        day[2]++;
    }
    m = 1; //从1月1号开始往后推,所以m = 1,d = 1 
    d = 1;
    sf = 0; //如果当前是春节第一天,那么春节3天还剩 sf 天 
    ans = 0;  //假期总数 
    while(m < 13){
        if(m == mm[6] && d == dd[6]){  //给出的第二行二数即是春节,位置在mm[6]  dd[6],所以优先判断是否是春节 
            ans++;   //如果已经进入春节第一天,则春节假期还有 sf 天 
            sf = 2;
        }else if(sf){   //如果进入春节假期,则不断执行这里,直到结束春节假期 
            ans++;
            sf--;
        }else if(w == 6 || w == 7){   //看看是不是周末周六 
            ans++;
        }else{
            for(int i =0;i < 10;i++){     //看看该天在不在 给定的假期中 
                if(m == mm[i] && d == dd[i]){
                    ans++;
                    break;
                }
            }
        }
        nextday(y,m,d);  //下一天 
        w++;      //下一天是星期几 
        if(w == 8){
            w = 1;
        }
    }
    printf("%d",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/expedition/p/12275655.html