w:指星期,對7取模,0 -> 星期一 1 -> 星期二 2 -> 星期三 3 -> 星期四 4 -> 星期五 5 -> 星期六 6 -> 星期日
c:指世紀
y:指年份 一般情況下取後兩位,y % 100
m:指月份
d:指日
[] 代指取整,只取整數部分
蔡勒公式只適用於1582年10月15日之後的情形
蔡勒公式的模板:
int col(int year, int mon, int day){
if(mon == 1 || mon == 2) year--, mon += 12;
int c = year / 100;
int y = year - c*100;
int w = y + y/4 + c/4 - 2*c + 26*(mon+1)/10 + day - 1;
while(w < 0) w += 7;
return w % 7;
}
例題:2019牛客多校第六場Is Today Friday
題意:每組測試樣例給出n個長度爲10的字符串,該字符串由A~J的字母組成,讓你求是否有一組數字串可以使得字母字符串滿足星期五。
代碼:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int n;
int a[15], v[15];
string s[maxn];
map<string, int>vis;
set<string>cun;
int mm[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool pan(int x){
if((x % 400 == 0) || (x % 4 == 0 && x % 100)) return true;
else return false;
}
int col(int year, int mon, int day){
if(mon == 1 || mon == 2) year--, mon += 12;
int c = year / 100;
int y = year - c*100;
int w = y + y/4 + c/4 - 2*c + 26*(mon+1)/10 + day - 1;
while(w < 0) w += 7;
return w % 7;
}
bool check(int x[]){
set<string>::iterator it;
for(it = cun.begin(); it != cun.end(); it++){
int y = x[(*it)[0] - 'A'] * 1000 + x[(*it)[1] - 'A'] * 100 + x[(*it)[2] - 'A'] * 10 + x[(*it)[3] - 'A'];
int m = x[(*it)[5] - 'A'] * 10 + x[(*it)[6] - 'A'];
int d = x[(*it)[8] - 'A'] * 10 + x[(*it)[9] - 'A'];
if(y < 1600 || y > 9999) return false;
if(m < 1 || m > 12) return false;
int tmpm = mm[m];
if(m == 2 && pan(y)) tmpm = 29;
if(d < 1 || d > tmpm) return false;
int w = col(y, m, d);
if(w != 5) return false;
}
return true;
}
int main()
{
int T;
cin >> T;
for(int cas = 1; cas <= T; cas++){
cun.clear();
cin >> n;
for(int i = 1; i <= n; i++) cin >> s[i], cun.insert(s[i]);
for(int i = 0; i < 10; i++) a[i] = i;
cout << "Case #" << cas << ": ";
int flag = 0;
do{
if(check(a)){
flag = 1;
for(int i = 0; i < 10; i++) cout << a[i];
cout << endl;
break;
}
} while(next_permutation(a, a+10));
if(!flag){
cout << "Impossible" << endl;
}
}
}