【真题研究】CSP-S2020

[CSP-S2020] 儒略日#

大模拟。

可以将时间分为 4 个部分:

  1. 4713.1.11.12.31
  2. 1.1.11582.10.4
  3. 1582.10.51582.10.14
  4. 1582.10.15 至无穷

大体可分为公元前(儒略历),公元后儒略历,公元后格里高利历。

如果 x1721424,说明是公元前儒略历,4 年一打包,其中 1 个闰年和 3 个平年,共 1461 天。然后按周期推年份。推完年份剩下的天数用来推月份,天数即可,注意判断闰年。

void bc(int x) {
  int dY = x / zq1, i, op = 0; x %= zq1;
  for (i = 0; i < 4; i++) {
    if(i % 4 == 0 && x > 366) x -= 366;
    else if(i % 4 != 0 && x > 365) x -= 365;
    else break;
  }
  Y = 4713 - (dY * 4 + i);
  if(x == 0) {
    D = 31, M = 12;
    Y++;
    return ;
  }
  if(i == 0) op = 1;
  for (i = 1; i <= 12; i++) {
    int del = ((op && i == 2) ? Mth[i] + 1 : Mth[i]);
    if(x > del) x -= del;
    else break;
  }
  M = i;
  D = x;
  return ;
}

如果 1721424<x2299161,说明是公元后儒略历,和公元前儒略历类似,不过多赘述。

void BBC(int x) {
  int dY = x / zq1, i, op = 0; x %= zq1;
  for (i = 1; i <= 4; i++) {
    if(i % 4 == 0 && x > 366) x -= 366;
    else if(i % 4 != 0 && x > 365) x -= 365;
    else break;
  }
  Y = (dY * 4 + i);
  if(x == 0) {
    D = 31, M = 12;
    Y--;
    return ;
  }
  if(Y % 4 == 0) op = 1;
  for (i = 1; i <= 12; i++) {
    int del = ((op && i == 2) ? Mth[i] + 1 : Mth[i]);
    if(x > del) x -= del;
    else break;
  }
  M = i;
  D = x;
  return ;
}

然后是日期删除的部分,直接跳过1582.10.51582.10.15 日。然后进入到公元后格里高利历。由于 1582 年是从 10.15 开始的,所以要特判断掉这一年。到 1582.12.3178 天。

if(x <= 78) {
  if(x <= 17) {
    M = 10, D = 15+x-1;
  } else if(x <= 47) {
    x -= 17;
    M = 11, D = x;
  } else {
    x -= 47;
    M = 12, D = x;
  }
  Y = 1582;
  cout << D << ' ' << M << ' ' << Y << '\n';
  return ;
}

然后按 400 年为一周期打包,一个周期有 97 个闰年和 303 个平年,共 97×366+303×365=146097 天。推完年份剩下的天数用来推月份,天数即可,注意判断闰年需要把 1582 年和包内的年份一起算上判断。

int dY = (x / y400), i, op = 0; x %= y400;
for (i = 1; i <= 400; i++) {
  if(check(1582 + dY * 400 + i) && x > 366) x -= 366;
  else if(!check(1582 + dY * 400 + i) && x > 365) x -= 365;
  else break;
}
Y = 1582 + dY * 400 + i;
if(x == 0) {
  M = 12, D = 31;
  Y--;
  goto ans2;
}
if(check(Y)) op = 1;
for (i = 1; i <= 12; i++) {
  int del = ((op && i == 2) ? Mth[i] + 1 : Mth[i]);
  if(x > del) x -= del;
  else break;
}
M = i;
D = x;
ans2: cout << D << ' ' << M << ' ' << Y << '\n';

然后整合起来,分类讨论即可。

时间复杂度 O(q)

#include<bits/stdc++.h>
#define int long long
#define For(i,l,r) for(int i=l;i<=r;++i)
#define FOR(i,r,l) for(int i=r;i>=l;--i)

using namespace std;

const int Mth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

const int zq1 = 1461, BC = 1721424, k1582 = 577737, y400 = 146097;

int q, x, D, M, Y;

bool check(int x) {
  if(x % 400 == 0) return 1;
  if(x % 4 == 0 && x % 100 != 0) return 1;
  return 0;
}

void BBC(int x) {
  int dY = x / zq1, i, op = 0; x %= zq1;
  for (i = 1; i <= 4; i++) {
    if(i % 4 == 0 && x > 366) x -= 366;
    else if(i % 4 != 0 && x > 365) x -= 365;
    else break;
  }
  Y = (dY * 4 + i);
  if(x == 0) {
    D = 31, M = 12;
    Y--;
    return ;
  }
  if(Y % 4 == 0) op = 1;
  for (i = 1; i <= 12; i++) {
    int del = ((op && i == 2) ? Mth[i] + 1 : Mth[i]);
    if(x > del) x -= del;
    else break;
  }
  M = i;
  D = x;
  return ;
}

void bc(int x) {
  int dY = x / zq1, i, op = 0; x %= zq1;
  for (i = 0; i < 4; i++) {
    if(i % 4 == 0 && x > 366) x -= 366;
    else if(i % 4 != 0 && x > 365) x -= 365;
    else break;
  }
  Y = 4713 - (dY * 4 + i);
  if(x == 0) {
    D = 31, M = 12;
    Y++;
    return ;
  }
  if(i == 0) op = 1;
  for (i = 1; i <= 12; i++) {
    int del = ((op && i == 2) ? Mth[i] + 1 : Mth[i]);
    if(x > del) x -= del;
    else break;
  }
  M = i;
  D = x;
  return ;
}

void solve() {
  D = M = Y = 0;
  cin >> x; x++;
  if(x <= BC) {
    bc(x);
    cout << D << ' ' << M << ' ' << Y << " BC\n";
  } else {
    x -= BC;
    if(x <= k1582) {
      BBC(x);
      cout << D << ' ' << M << ' ' << Y << '\n';
    } else {
      x -= k1582;
      if(x <= 78) {
        if(x <= 17) {
          M = 10, D = 15+x-1;
        } else if(x <= 47) {
          x -= 17;
          M = 11, D = x;
        } else {
          x -= 47;
          M = 12, D = x;
        }
        Y = 1582;
        cout << D << ' ' << M << ' ' << Y << '\n';
        return ;
      }
      x -= 78;
      int dY = (x / y400), i, op = 0; x %= y400;
      for (i = 1; i <= 400; i++) {
        if(check(1582 + dY * 400 + i) && x > 366) x -= 366;
        else if(!check(1582 + dY * 400 + i) && x > 365) x -= 365;
        else break;
      }
      Y = 1582 + dY * 400 + i;
      if(x == 0) {
        M = 12, D = 31;
        Y--;
        goto ans2;
      }
      if(check(Y)) op = 1;
      for (i = 1; i <= 12; i++) {
        int del = ((op && i == 2) ? Mth[i] + 1 : Mth[i]);
        if(x > del) x -= del;
        else break;
      }
      M = i;
      D = x;
      ans2: cout << D << ' ' << M << ' ' << Y << '\n';
    }
  }
}

signed main() {
  ios::sync_with_stdio(0);
  cin.tie(nullptr), cout.tie(nullptr);
  cin >> q;
  while(q--) solve();
  return 0;
}

[CSP-S2020] 动物园#

很狗屎的题。

m 个饲料约束条件。如果有条件但是现有的动物没有一个满足的,说明此条件对应的饲料买不到了,因此新加的动物中不能有动物需要这款饲料。

翻译过来就是将 ai 全部或运算起来,得到的二进制数。如果条件中 qi 的位置为 0,则累计贡献 Ans 一次。最后满足条件的动物数量便为 2kAns。新增的动物数量为 2kAnsn

时间复杂度 O(n+m),最后一个点会爆 long long,记得开 __int128

#include<bits/stdc++.h>
#define int __int128
#define rint register int
#define For(i,l,r) for(int i=l;i<=r;++i)
#define FOR(i,r,l) for(int i=r;i>=l;--i)

using namespace std;

inline int read() {
  rint x=0,f=1;char ch=getchar();
  while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
  return x*f;
}

inline void print(int x) {
  if(x > 9) {
    print(x/10);
    putchar(x%10+'0');
  } else {
    putchar(x+'0');
  }
}

const int N = 1e6 + 10;

int n, m, c, k, a[N], Ans;

bitset<64> ans;

bool vis[65];

signed main() {
  n = read(), m = read(), c = read(), k = read();
  For(i,1,n) {
    a[i] = read();
    bitset<64> pos(a[i]);
    ans |= pos;
  }
  For(i,1,m) {
    int p = read(), q = read();
    if(ans[p] == 0 && !vis[p]) Ans++, vis[p] = 1;
  }
  print(((__int128)1 << (k - Ans)) - n);
  return 0;
}

作者:Daniel-yao

出处:https://www.cnblogs.com/Daniel-yao/p/18499136

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   Daniel_yzy  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示