Sicily.1125. Arnie versus the IRS(统计时间段内各个数字出现次数,不算周六日)

/*1125. Arnie versus the IRS(统计时间段内各个数字出现次数,不算周六日)
  大意:给出一个时间段,求出时间段内出周六日外的全部日期的所有数字出现次数 
  思路:先确定日期是周几。然后再分割日期,用map来统计各个数字出现次数 
*/
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <math.h>
#include <map>
using namespace std;

int originWeekDay = 3; //1920年1月1日为周四 
int originYear = 1920;

int startYear, startMonth, startDay;
int endYear, endMonth, endDay;
map<int, int> m;
map<int, int> m1;
void initMap(){
   m[1] = 31;
   m[2] = 28;
   m[3] = 31;
   m[4] = 30;
   m[5] = 31;
   m[6] = 30;
   m[7] = 31;
   m[8] = 31;
   m[9] = 30;
   m[10] = 31;
   m[11] = 30;
   m[12] = 31;
}

void initMap2(){
   m1[0] = 0;
   m1[1] = 0;
   m1[2] = 0;
   m1[3] = 0;
   m1[4] = 0;
   m1[5] = 0;
   m1[6] = 0;
   m1[7] = 0;
   m1[8] = 0;
   m1[9] = 0;
}

bool isRunYear(int year){
     if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
       return true;
    return false;
}

int calWeekDay(int year, int month, int day){
    int differ = 0;
    for(int i =originYear; i<= year; i++){
       for(int mon = 1; mon <= ( i == year ?  month : 12); mon++){
          int dayNum; 
          if(mon == 2 && isRunYear(i)){     
                 dayNum = m[2] + 1;                  
          }
          else
             dayNum = m[mon];
          int acDay = (i == year && mon == month) ? day : dayNum;
          
          for(int d = 1; d <=acDay; d++){
               differ++;    
          }       
       } 
        
    }
    differ--;
    int temp = (originWeekDay+ differ) % 7;
    return temp ;
}

void calDigit(int sYear, int sMonth, int sDay, int eYear, int eMonth, int eDay, int sWeekday){
    int differ = 0;
    for(int year=sYear; year<= eYear; year++){
      
       for(int mon = sMonth; mon <= ( year == eYear ?  eMonth : 12); mon++){
          int dayNum; 
          
          if(mon == 2 && isRunYear(year)){     
             dayNum = m[2] + 1;                  
          }
          else
             dayNum = m[mon];
          int acDay = (year == eYear && mon == eMonth) ? eDay : dayNum;
          int acSDay =(year == sYear && mon == sMonth) ? sDay : 1;
          for(int day = acSDay; day <=acDay; day++){
               if(sWeekday == 5 || sWeekday == 6) {
                  sWeekday = (sWeekday+1)%7;
                  continue;
               }
               sWeekday = (sWeekday+1)%7;
               differ++;   
               int tempYear = year;
               int tempMon = mon;
               int temDay = day;
               while(tempYear != 0 ){
                   m1[tempYear % 10]++;
                   tempYear /= 10;               
               }
               int level = 0;
               while(tempMon != 0 ){
                   m1[tempMon % 10]++;
                   tempMon /= 10;
                   level++;               
               }
               if(level == 1)
                 m1[0]++;   
               level = 0;
               while(temDay != 0 ){
                   m1[temDay % 10]++;
                   temDay /= 10;
                   level++;               
               }
               if(level == 1)
                 m1[0]++; 
          }       
       }   
    }
     
}
int main()
{ 
    initMap();
    string start, end;
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
     bool ok = false;
    while( cin >> start >> end) {
           if(ok)
            cout << endl;
           ok =true;
          initMap2();
          startMonth = atoi((start.substr(0,2)).c_str());
          startDay = atoi((start.substr(3,5)).c_str()) ;
          startYear = atoi((start.substr(6,9)).c_str()) ;
          
          endMonth = atoi((end.substr(0,2)).c_str());
          endDay = atoi((end.substr(3,5)).c_str()) ;
          endYear = atoi((end.substr(6,9)).c_str());

           int startWeekday = calWeekDay(startYear, startMonth, startDay) ;
           calDigit(startYear, startMonth,startDay , endYear, endMonth, endDay, startWeekday);
           for(int i=0; i<=9; i++)
           {
             cout << i  << " " << m1[i] << endl; 
           }
           //cout << endl;
    }
    //cout << endl;
    //system("pause");
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值