[COCI2022-2023 #5] Kalendar 题解

· · 题解

本题要求你画出一个日历。

首先,如果 x>1,那么日历的第一行(不包括装饰部分)就需要补上占 x-1 日位置的点。然后把第一行补齐,第二行开始从第一行最后一个日期 +1 不断往下枚举,如果当前枚举到的点是一行的开头,就输出一个 |,否则如果是一个行的末尾就输出一个 | 和一个换行即可。最后一行可能有空缺,计算出空出的天数,用点补上即可。

这里介绍一个 setfill() 函数。我们常用的 setw() 函数如果不结合该函数使用,只能用空格作为占位的字符,但是 setfill() 函数可以指定占位的字符,用法如下:

int w=6; // 场宽
char c='Q'; // 占位字符
cout<<setw(w)<<setfill(c)<<2303;
// 输出即为 QQ2303

放代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
  ios::sync_with_stdio(false);
  int n,x,a; cin>>n>>x; a=(8-x)%7;
  cout<<"+---------------------+\n"; // 日历头
  if(x>1){
    cout<<'|';
    for(int i=1;i<x;i++)cout<<"..."; // 补齐开头缺的日子
    for(int i=1;i<=min(n,a);i++)cout<<setw(3)<<setfill('.')<<i; // 第一行剩下的日子
    if(a<=n)cout<<"|\n"; // 如果这一行不是最后一行,就输出一个 '|' 和一个换行
  }
  for(int i=a+1;i<=n;i++){
    if((i-a)%7==1)cout<<'|'; // 行的开头
    cout<<setw(3)<<setfill('.')<<i; // 输出日子
    if(!((i-a)%7))cout<<"|\n"; // 行的末尾
  }
  if(((1-n-x)%7+7)%7){
    for(int i=1;i<=((1-n-x)%7+7)%7;i++)cout<<"...";
    cout<<"|\n"; // 补齐最后的一行
  }
  cout<<"+---------------------+\n"; // 日历脚
  return 0;
}