어느 날 이 무슨 요일 인지 마음대로 부탁 하 다.

17906 단어 데이터 구조
1. 문제 제기
우 리 는 텔레비전 등 예능 프로그램 에서 도 자주 볼 수 있다. 어떤 사람들 은 그 날 이 무슨 요일 인지 빨리 대답 할 수 있다 고 말한다. 바로 살 아 있 는 달력 이 라 고 할 수 있다. 오늘 나 는 프로 그래 밍 을 통 해 이 문 제 를 실현 했다.처음에 이 문 제 를 한 것 은 ccf 인증 시험 에서 이런 문제 가 나 왔 다 는 것 이다.문 제 는 명절 의 날 짜 는 고정된 것 이 아니 라 'a 월 의 b 번 째 주 c' 의 형식 으로 정 해진 것 이다. 예 를 들 어 어머니 의 날 은 매년 5 월 의 두 번 째 일요일 로 정 해진 다.현재, a, b, c 와 y1, y2 (1850 ≤ y1, y2 ≤ 2050) 를 드 립 니 다. 서기 y1 년 에서 서기 y2 년 간 의 매년 a 월 의 b 번 째 주 c 의 날 짜 를 수출 하 시기 바 랍 니 다.힌트: 윤년 에 관 한 규칙: 연 도 는 400 의 정수 배 일 때 윤년 이다. 그렇지 않 으 면 연 도 는 4 의 배수 이 고 100 의 배수 가 아 닐 때 윤년 이 며 다른 해 는 윤년 이 아니다.예 를 들 어 1900 년 은 윤년 이 아니 라 2000 년 은 윤년 이다.당신 의 추산 을 편리 하 게 하기 위해 서, 이미 1850 년 1 월 1 일이 화요일 이라는 것 을 알 고 있 습 니 다.입력 형식 입력 은 딱 한 줄 을 포함 하고 다섯 개의 정수 a, b, c, y1, y2 가 있 습 니 다.그 중에서 c = 1, 2,..., 6, 7 은 각각 월요일, 화요일,..., 6, 일 을 나타 낸다.출력 형식 은 y1 과 y2 사이 의 모든 연도 에 대해 y1 과 y2 를 포함 하여 연도 에 따라 어 릴 때 부터 큰 순서 로 한 줄 을 출력 합 니 다.만약 에 이 해 의 a 월 b 주 c 가 존재 한다 면 'yyy / mm / dd' 의 형식 으로 출력 합 니 다. 즉, 네 자릿수 를 출력 하 는 년도, 두 자릿수 의 달, 두 자릿수 의 날짜, 중간 에 슬 래 쉬 '/' 로 구분 되 고 자릿수 가 부족 할 때 0 을 보충 합 니 다.이 해 의 a 월 b 번 째 주 c 가 존재 하지 않 으 면 "none" (더 블 따옴표 포함 하지 않 음) 을 출력 합 니 다. 샘플 입력 5 27 2014 2015 사례 출력 2014 / 05 / 11 2015 / 05 / 10 평가 사례 규모 와 약정 한 모든 평가 사례 만족: 1 ≤ a ≤ 12, 1 ≤ b ≤ 5, 1 ≤ c ≤ 7, 1850 ≤ y1, y2 ≤ 2050.
이 문 제 는 실질 적 으로 어느 날 이 무슨 요일 인지 구 하 는 것 이다.
2. 기본 적 인 사고방식
제목 에서 1850 년 1 월 1 일이 화요일 이 라 고 알려 주 었 다. 1850 년 이후 지금까지 모두 며칠 이 지 났 는 지 계산 한 다음 에 7 에 여 유 를 구 할 수 있다. 서로 다른 해 는 평년 과 윤년 의 구분 이 있 고 평년 은 365 일 이 며 7 에 여 유 는 1 이 며 윤년 은 366 일 이 며 7 에 여 유 는 2 이다. 즉, 우 리 는 매 해 의 일 수 를 정확하게 구하 지 않 아 도 이 질문 을 풀 수 있다 는 것 이다.문제 입 니 다. 우 리 는 심지어 매 해 가 평년 인지 윤년 인지 구 할 필요 도 없 이 이 문 제 를 해결 할 수 있 습 니 다. 계산 을 통 해 1852 년 이 윤년 인 것 을 발 견 했 습 니 다. 현재 의 연 도 를 1852 년 에서 빼 면 지난 몇 개의 윤년 을 대충 계산 할 수 있 습 니 다. 물론 그 중에서 100 년 의 문 제 를 고려 해 야 합 니 다. 예 를 들 어 1900 - 1999 년 사이 에 1852 년 에서 나 온 윤년 수 를 계산 하면 1 을 줄 여야 합 니 다.다음 코드 에서 weekday 는 일주일 의 며칠 이 고 일요일 은 0 이 며 월요일 부터 토요일 은 각각 1 - 6 이다.
#include

int main(){
    int year=2000;//    
    int weekday=0;
    if(year>1852)
        weekday=(year-1-1852)/4+1;// 1852          
    if(year>1900)weekday--;//2000     ,      
    weekday+=(year-1850);
    weekday+=2;//1850 1 1     
    weekday%=7;
    printf("%d",weekday);
    return 0;
}

이상 의 코드 는 매년 1 월 1 일이 무슨 요일 인지 계산 할 수 있 습 니 다. 같은 방법 으로 우 리 는 어느 날 이 무슨 요일 인지 구 할 수 있 습 니 다. 이 를 위해 우 리 는 현재 달의 1 일 에서 1 월 1 일 까지 의 일 수 를 표시 하 는 배열 을 구축 할 수 있 습 니 다.
static int monday[12]={0,31,31+28,31+28+31,31+28+31+30,31+28+31+30+31,
    31+28+31+30+31+30,31+28+31+30+31+30+31,31+28+31+30+31+30+31+31,
    31+28+31+30+31+30+31+31+30,31+28+31+30+31+30+31+31+30+31,31+28+31+30+31+30+31+31+30+31+30}; 

c 언어 에서 상기 덧셈 은 컴 파일 할 때 계산 되 며, 프로그램 이 실 행 될 때 구체 적 인 값 을 계산 하 는 것 이 아니 라 gcc - S 를 통 해 어 셈 블 리 코드 로 컴 파일 하여 상세 하 게 알 수 있 습 니 다. 그러면 우 리 는 임의의 하루 가 무슨 요일 인지 구 할 수 있 습 니 다. 이러한 방법 역시 심산 하여 자신 을 달력 으로 만 들 수 있 습 니 다. 다음은 모든 코드 입 니 다.
#include
static int monday[12]={0,31,31+28,31+28+31,31+28+31+30,31+28+31+30+31,
    31+28+31+30+31+30,31+28+31+30+31+30+31,31+28+31+30+31+30+31+31,
    31+28+31+30+31+30+31+31+30,31+28+31+30+31+30+31+31+30+31,31+28+31+30+31+30+31+31+30+31+30};

int main(){
    int year=2016,month=3,day=23;//    
    int weekday=0;
    if(year>1852)
        weekday=(year-1-1852)/4+1;// 1852          
    if(year>1900)weekday--;//2000     ,      
    weekday+=(year-1850);
    weekday+=2;//1850 1 1     
    weekday+=monday[month-1];//month 1  
    if(month>2&&(year%400==0||(year%4==0&&year%100!=0))){
        printf("fdsa");
        weekday++;
    }
    weekday+=(day-1);//day 1  
    weekday%=7;
    printf("%d",weekday);
    return 0;
}

마지막 으로 ccf 문제 의 코드 를 동봉 합 니 다. 이 코드 는 제 가 예전 에 쓴 것 입 니 다. 위의 코드 와 일치 하지 않 는 부분 이 많 지만 기본 적 인 사상 은 같 습 니 다.
#include 

#define isleap(n) ((n%400==0||(n%4==0&&n%100!=0))) 

int getday(int y,int m){
    static int monday[12]={0,31,31+28,31+28+31,31+28+31+30,31+28+31+30+31,
    31+28+31+30+31+30,31+28+31+30+31+30+31,31+28+31+30+31+30+31+31,
    31+28+31+30+31+30+31+31+30,31+28+31+30+31+30+31+31+30+31,31+28+31+30+31+30+31+31+30+31+30}; 
    int day=(y-1850)*365;
    day=day+(int)((y-1849)/4);
    if(y>1900)
        day--;
     day++;

    day+=monday[m-1];
    if(m>2&&isleap(y))
        day++; 
    return day%7+1;
} 

int main(){
    int m,n,k,y1,y2; 
    scanf("%d %d %d %d %d",&m,&n,&k,&y1,&y2);
    int a=getday(y1,m);
    int b=getday(y2,m);
    int day1,day2;
    day1=1+(k-a)+7*(n-1);
    day2=1+(k-b)+7*(n-1);
    if(y1if(day1<0||day1>31) 
            printf("none
"
); else printf("%04d/%02d/%02d
"
,y1,m,day1); if(day2<0||day2>31) printf("none
"
); else printf("%04d/%02d/%02d",y2,m,day2); }else{ if(day2<0||day2>31) printf("none
"
); else printf("%04d/%02d/%02d",y2,m,day2); if(day1<0||day1>31) printf("none
"
); else printf("%04d/%02d/%02d
"
,y1,m,day1); } return 0; }

좋은 웹페이지 즐겨찾기