牛客多校第六场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 ...
随机推荐
- mysql InnoDB架构
1.InnoDB的磁盘结构 1)系统表空间 2)用户表空间 3)rodolog 文件组 4)磁盘文件逻辑结构 文件->段->区->页->行 InnoDB对数据的存取是以页为单位 ...
- springboot项目启动并立即执行自定义程序内容
第一种:实现ApplicationRunner接口,重写其中的run()方法: 第二种:实现CommandLineRunner接口,重写其中的run()方法: 还有第三种...
- uni-app 微信小程序 picker 三级联动
之前做过一个picker的三级联动功能,这里分享代码给大家 具体代码: // An highlighted block <template> <view> <picker ...
- ant design vue 地区选择(级联)
city.js const options = [ { value:'北京市', label:'北京市', children:[ { value:'北京市', label:'北京市', childre ...
- Vue基础之生命周期函数[残缺版]!
Vue基础之生命周期函数[残缺版]! 为什么说是残缺版呢?! 因为有一些周期函数我并没有学到!所以是残缺版! 01 beforeCreate //在实例初始化之后,数据观测 (data observe ...
- rehash (重新散列)
rehash - Redis 设计与实现 http://redisbook.com/preview/dict/rehashing.html
- 阿里云服务器centos7,docker部署mysql+Redis+vue+springboot+Nginx+fastdfs,亲测可用
一.购买云服务器 我是今年双十一期间在阿里云购买的服务器, 简单配置2核_4G_40G_3M,三年用了不到800块,不过当时我记得腾讯云更便宜,个人感觉,阿里的云服务器更加的稳定, 毕竟身经百战, 经 ...
- loj10161 叶子的颜色
CQOI 2009 给一棵有 mm 个节点的无根树,你可以选择一个度数大于 11 的节点作为根,然后给一些节点(根.内部节点.叶子均可)着以黑色或白色.你的着色方案应保证根节点到各叶子节点的简单路径上 ...
- python基础学习2 函数变量与赋值
学习的第一步,就是通常的输出函数:print() 1.基础主要学习了变量的赋值,变量名可以疑字母.数字.下划线(_)进行命名,但是不能以数字开头 变量的赋值:变量名 = 变量值 2.模块的导入,和调用 ...
- Flink-v1.12官方网站翻译-P028-Custom Serialization for Managed State
管理状态的自定义序列化 本页面的目标是为需要使用自定义状态序列化的用户提供指导,涵盖了如何提供自定义状态序列化器,以及实现允许状态模式演化的序列化器的指南和最佳实践. 如果你只是简单地使用Flink自 ...