CCF-CSP的第三题们么

啊 这个题目长的让人恐慌

20150303 节日


//技不如人 之前做的太恶心了 直接计算出来总时间再判断星期几
//我发现我老是喜欢把时间拆成1块1块
//题不难 照着我那又也能写出来就是很长很恶心罢了

#include<bits/stdc++.h>
using namespace std;
//https://wannianli.tianqi.com/2009/01/
//绝了绝了真到考场了我这个题肯定不拿分因为跟我往常理解的不一样
int months[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//!!!!!
//!关于数组的这一个 都是从0开始 想从1开始数组长度+1 0随便赋值
bool isr(int year){
     return ((year%4 == 0 && year%100 != 0) || year%400 == 0) ? 1 : 0;
}
int main(){

    int a,b,c,y1,y2;
    cin>>a>>b>>c>>y1>>y2;
    int sum1=0;
    for(int i=1850;i<y1;i++){
        sum1+=365+isr(i);
    }//计算出截至到y1年的天数
    int day1=sum1;
    int d=0;//算那天号数


    for(int i=y1;i<=y2;i++){
       if(isr(i)==1){
          months[2]=29;
       }else{
          months[2]=28;
       }//用这种方式就很容易处理平年闰年的问题啊

       day1=sum1;
       for(int i=1;i<a;i++){
          day1+=months[i];
       }//截止到本年的a月的前一天


       int lastweekday=(1+day1)%7; // 计算i年a月1日的前一天为星期几 到本月1号的话就是(2+d)%7

       // 计算i年的a月第b个星期c是当月的几号
       d = (b-1)*7+(lastweekday<c?c-lastweekday:c-lastweekday+7);
       //!!!绝了这个地方;a月的第b个星期c 应该是a月的/第b个/星期c 而不是a月的第b个星期/(星期)c
       //!!万一本月从星期五开始 那第一个星期四??是7号啊
       if(d>months[a]){
        cout<<"none"<<endl;//如果该年的a月第b个星期c并不存在,则输出"none":直接算出来日期看有没有超过31/30/29/28不就得了  不需要像自己想的把具体星期几算出来
       }else{
         cout<<i<<"/";
         if(a<10){
            cout<<"0";
         }cout<<a<<"/";
         if(d<10){
            cout<<"0";
         }cout<<d<<endl;

       }
       sum1 += (365+isr(i));//!!注意这里得是sum1:专门整年整年的加 day1不行加了月份了
    }

     return 0;
}
/*
我的惊天大做法倒也不是没有好处
1850年的1.1号是星期2 1851则是星期三 1853是星期四 1854则是星期五
平年后的第二年1.1=平年1.1+1后%7
闰年                 闰年   +2
已知本年1.1号星期X  求具体日期 月份相加和+x后%7
不过在这种情况下 星期日表示为0;

*/

20150903 模板生成系统

还是看的海岛blog大佬的 题目不难理解 就是简单的字符串替换
关键是:

  1. 程序用需要用函数getline()来读入一行
  2. 因为C++的cin输入字符串时,无法输入空串和读入空格,而C的库函数中已经不建议使用函数gets(),所以在cin>>n>>m后需要用getchar()把空行吸了
  3. 模板的各个行,用字符串向量vector来存储比较有效。
    4.getline(cin,temp)函数:输入流/输入存储到temp https://blog.csdn.net/duan19920101/article/details/50782816
    5.string::npos: https://blog.csdn.net/lmb1612977696/article/details/81455708
    6.vector的find函数
    7.string.substr(开始位置,截取长度)
#include<bits/stdc++.h>

using namespace std;

int main(){

    int n,m;
    cin>>n>>m;getchar();
    vector<string> tv;//储存模型语句的
    string key,value;//M行的键值对
    string modeltemp;
    int prev,next;//待会要用到vector的find
    map<string,string>mdict;

    for(int i=1;i<=n;i++){
        getline(cin,modeltemp);///!
        tv.push_back(modeltemp);//push_back
    }
    for(int i=1;i<=m;i++){
        cin>>key;
        getline(cin,value);//
        mdict[key]=value.substr(2,value.length()-3);
        //因为值都是 用双引号 (") 括起来/下标从0开始
    }
    //储存完毕

    //替换
    for(int i=0;i<n;i++){//vector下标从0开始
        prev=0;
        for(;;){
            if((prev=tv[i].find("{{ ",prev))==(int)string::npos) break;//注意{{ 后面必须有空格
            //如果没找到 证明这行不需要替换 直接跳出for循环到下一行
            if((next=tv[i].find(" }}",prev))==(int)string::npos) break;

            //这行有替换的地方:先找到{{}}包裹的位置 拿到key 再整个替换 避免递归替换

            key=tv[i].substr(prev+3,next-prev-3);//prev是上面if语句里{{的位置

            tv[i].replace(prev,next-prev+3,mdict.count(key)?mdict[key]:"");
            //整个要替换肯定从{{开始到}}结束  //m行的输入里有这个值就替换 没有变成""

            prev+=mdict.count(key)?mdict[key].length():0;//避免重复替换 直接整个长度过去 不在这个被替换的string中判读有没有"key"

       }//替换就与要在for循环里 万一这一行有很多个需要替换的地方

       cout<<tv[i]<<endl;
    }

    return 0;
}
posted @ 2021-03-07 15:30  像走了一光年  阅读(120)  评论(0编辑  收藏  举报