牛客多校第六场G Is Today Friday?(吉姆拉尔森/蔡勒公式 + 思维)题解
题意:
给你\(A-J\)的字母组成的日期,形式为\(yyyy/mm/dd\)。现给你\(n\)个这样的串\((n<=1e5)\),问你把字母映射成数字,并且使得所有日期合法且为星期五的最小字典序为什么。
思路:
判断星期几可以直接用吉姆拉尔森公式解决。
inline int weekday(int y, int m, int d){
\(\qquad\)if(m <= 2){m += 12, y--;}
\(\qquad\)return (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7 + 1;
}
因为合法的日期其实很少,就只有几万种,但是\(n\)太大了,但是由于合法日期其实远远比n小,那么这里面其实有很多重复的日期,那么我们先除重,这样就能减少很多判断的地方。
代码:
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<cmath>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 100000 + 5;
const int INF = 0x3f3f3f3f;
const ull seed = 131;
const ll MOD = 1e9 + 7;
using namespace std;
inline int weekday(int y, int m, int d){
if(m <= 2){m += 12, y--;}
return (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7 + 1;
}
int day[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
char ye[maxn][4], mo[maxn][2], da[maxn][2];
string s[maxn];
int n, vis[maxn], mean[20];
int tot, choose[maxn][20], ok;
bool check(int n, int *mean){
for(int i = 1; i <= n; i++){
int y = 0;
for(int j = 0; j < 4; j++) y = y * 10 + mean[ye[i][j] - 'A'];
if(y < 1600 || y > 9999) return false;
int m = 0;
for(int j = 0; j < 2; j++) m = m * 10 + mean[mo[i][j] - 'A'];
if(m < 1 || m > 12) return false;
int d = 0;
for(int j = 0; j < 2; j++) d = d * 10 + mean[da[i][j] - 'A'];
if(d < 1 || d > 31) return false;
if(y % 400 == 0 || (y % 100 != 0 && y % 4 == 0)){
if(m == 2 && d > 29) return false;
if(m != 2 && d > day[m]) return false;
}
else if(d > day[m]) return false;
if(weekday(y, m, d) != 5) return false;
}
return true;
}
void dfs(int cnt){
if(cnt + 'A' > 'J'){
if(check(min(n, 100), mean)){
ok = 1;
for(int i = 0; i <= 9; i++)
choose[tot][i] = mean[i];
tot++;
}
return;
}
for(int i = 0; i <= 9; i++){
if(!vis[i]){
vis[i] = 1;
mean[cnt] = i;
dfs(cnt + 1);
vis[i] = 0;
}
}
}
int main(){
int T, ca = 1;
scanf("%d", &T);
while(T--){
scanf("%d", &n);
for(int i = 1; i <= n; i++) cin >> s[i];
sort(s + 1, s + n + 1);
n = unique(s + 1, s + n + 1) - s - 1;
for(int i = 1; i <= n; i++){
for(int j = 0; j < 4; j++) ye[i][j] = s[i][j];
for(int j = 5; j < 7; j++) mo[i][j - 5] = s[i][j];
for(int j = 8; j < 10; j++) da[i][j - 8] = s[i][j];
}
memset(vis, 0, sizeof(vis));
tot = 0;
dfs(0);
ok = -1;
for(int i = 0; i < tot; i++){
if(check(n, choose[i])){
ok = i;
break;
}
}
printf("Case #%d: ", ca++);
if(ok != -1){
for(int i = 0; i <= 9; i++) printf("%d", choose[ok][i]);
puts("");
}
else{
printf("Impossible\n");
}
}
return 0;
}
牛客多校第六场G Is Today Friday?(吉姆拉尔森/蔡勒公式 + 思维)题解的更多相关文章
- 2018牛客多校第六场 G.Pikachu
题意: 给出一棵n个点的树,每条边有边权.对这个树加边变成一个完全图.新加的边的权值为边上两点在树上的距离.求完全图上任意两点的最大流之和. 题解: 一共有C(n,2)个点对.假设当前求s到t之间的最 ...
- 牛客多校第六场 G Is Today Friday? 蔡勒公式/排列
题意: 有一堆日期,这些日期都是星期五,但是数字被映射成了字母A~J,现在让你求逆映射,如果存在多种答案,输出字典序最小的那个. 题解: 用蔡勒公式解决关于星期几的问题. 对于映射,可以用笔者刚刚学会 ...
- 牛客多校第三场 G Removing Stones(分治+线段树)
牛客多校第三场 G Removing Stones(分治+线段树) 题意: 给你n个数,问你有多少个长度不小于2的连续子序列,使得其中最大元素不大于所有元素和的一半 题解: 分治+线段树 线段树维护最 ...
- 牛客多校第四场 G Maximum Mode
链接:https://www.nowcoder.com/acm/contest/142/G来源:牛客网 The mode of an integer sequence is the value tha ...
- 牛客多校第六场 C Generation I 组合数学 阶乘逆元模板
链接:https://www.nowcoder.com/acm/contest/144/C来源:牛客网 Oak is given N empty and non-repeatable sets whi ...
- 牛客多校第六场 J Heritage of skywalkert 随即互质概率 nth_element(求最大多少项模板)
链接:https://www.nowcoder.com/acm/contest/144/J来源:牛客网 skywalkert, the new legend of Beihang University ...
- 牛客多校第六场-H-Pair
链接:https://ac.nowcoder.com/acm/contest/887/H来源:牛客网 题目描述 Given three integers A, B, C. Count the numb ...
- 字符串dp——牛客多校第五场G
比赛的时候脑瘫了没想出来..打多校以来最自闭的一场 显然从s中选择大于m个数组成的数必然比t大,所以只要dp求出从s中选择m个数大于t的方案数 官方题解是反着往前推,想了下反着推的确简单,因为高位的数 ...
- 2018牛客多校第六场 I.Team Rocket
题意: 给出n个区间和m个点(点按顺序给出且强制在线).每个区间只会被第一个他包含的点摧毁.问每个点能摧毁多少个区间以及每个区间是被哪个点摧毁的. 题解: 将n个区间按照左端点排序,然后用vector ...
随机推荐
- Android事件分发机制二:viewGroup与view对事件的处理
前言 很高兴遇见你~ 在上一篇文章 Android事件分发机制一:事件是如何到达activity的? 中,我们讨论了触摸信息从屏幕产生到发送给具体 的view处理的整体流程,这里先来简单回顾一下: 触 ...
- Effective Java, 3e阅读笔记一
引言 本书的目标是帮助读者更加有效地使用Java编程语言及其基本类库,适用于任何具有实际Java工作经验的程序员. 本书一共90个条目,12章,每个条目讨论一条规则,这些规则反映了最有经验的优秀程序员 ...
- Java运算符及包机制
Java中的运算符及包机制 算术运算符:+ - * / % ++ -- 赋值运算符:=,+=,-=,*=,/= 关系运算符:>,<,>=,<=,==,!=,instanceof ...
- pymysql模块使用介绍
pymysql 我们要学的pymysql就是用来在python程序中如何操作mysql,本质上就是一个套接字客户端,只不过这个套接字客户端是在python程序中用的,既然是客户端套接字,应该怎么用 ...
- vue组件中data为什么必须是一个函数?
因为JavaScript的特性所导致,在component中,data必须以函数的形式存在,不可以是对象. 组建中的data写成一个函数,数据以函数返回值的形式定义,这样每次复用组件的时候,都会返回一 ...
- 石子游戏(nim游戏+按位考虑)
题意 给\(n\)堆石子,每次最多可以从一堆中取\(x\)个,问你\(x = 1 ... n\)时的答案. 解法 经典\(nim\)游戏,找规律知\(sg[i] = i \ mod \ (x+1)\) ...
- 详述C++casting操作
Casting----类型转换,也就是将数据从一种类型转换到另一种类型的操作.本文首先给出两种类型转换的方式:隐式转换和显式转换,然后简单介绍一下C语言常用的类型转换方式,最后详细叙述C++中常用的三 ...
- Linux常用命令详解(第三章)(ping、kill、seq、du、df、free、date、tar)
本章命令(共7个): 1 2 3 4 5 6 7 8 ping kill seq du df free date tar 1." ping " 作用:向网络主机发送ICMP(检测主 ...
- (24)bzip2命令:压缩文件(.bz2格式)&&bunzip2命令:bz2格式的解压缩命令
1.bzip2 命令同 gzip 命令类似,只能对文件进行压缩(或解压缩),对于目录只能压缩(或解压缩)该目录及子目录下的所有文件.当执行压缩任务完成后,会生成一个以".bz2"为 ...
- php小程序-文章发布系统
php小程序-文章发布系统 一 项目相关视图 二 项目经验 主要用于熟悉php与mysql的相关操作 三 源码下载地址 http://files.cnblogs.com/files/qiujun/ar ...