题意:

给你\(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?(吉姆拉尔森/蔡勒公式 + 思维)题解的更多相关文章

  1. 2018牛客多校第六场 G.Pikachu

    题意: 给出一棵n个点的树,每条边有边权.对这个树加边变成一个完全图.新加的边的权值为边上两点在树上的距离.求完全图上任意两点的最大流之和. 题解: 一共有C(n,2)个点对.假设当前求s到t之间的最 ...

  2. 牛客多校第六场 G Is Today Friday? 蔡勒公式/排列

    题意: 有一堆日期,这些日期都是星期五,但是数字被映射成了字母A~J,现在让你求逆映射,如果存在多种答案,输出字典序最小的那个. 题解: 用蔡勒公式解决关于星期几的问题. 对于映射,可以用笔者刚刚学会 ...

  3. 牛客多校第三场 G Removing Stones(分治+线段树)

    牛客多校第三场 G Removing Stones(分治+线段树) 题意: 给你n个数,问你有多少个长度不小于2的连续子序列,使得其中最大元素不大于所有元素和的一半 题解: 分治+线段树 线段树维护最 ...

  4. 牛客多校第四场 G Maximum Mode

    链接:https://www.nowcoder.com/acm/contest/142/G来源:牛客网 The mode of an integer sequence is the value tha ...

  5. 牛客多校第六场 C Generation I 组合数学 阶乘逆元模板

    链接:https://www.nowcoder.com/acm/contest/144/C来源:牛客网 Oak is given N empty and non-repeatable sets whi ...

  6. 牛客多校第六场 J Heritage of skywalkert 随即互质概率 nth_element(求最大多少项模板)

    链接:https://www.nowcoder.com/acm/contest/144/J来源:牛客网 skywalkert, the new legend of Beihang University ...

  7. 牛客多校第六场-H-Pair

    链接:https://ac.nowcoder.com/acm/contest/887/H来源:牛客网 题目描述 Given three integers A, B, C. Count the numb ...

  8. 字符串dp——牛客多校第五场G

    比赛的时候脑瘫了没想出来..打多校以来最自闭的一场 显然从s中选择大于m个数组成的数必然比t大,所以只要dp求出从s中选择m个数大于t的方案数 官方题解是反着往前推,想了下反着推的确简单,因为高位的数 ...

  9. 2018牛客多校第六场 I.Team Rocket

    题意: 给出n个区间和m个点(点按顺序给出且强制在线).每个区间只会被第一个他包含的点摧毁.问每个点能摧毁多少个区间以及每个区间是被哪个点摧毁的. 题解: 将n个区间按照左端点排序,然后用vector ...

随机推荐

  1. 1V转3.3V稳压供电的芯片电路图

    1V转3.3V供电是简单的,仅需要一个芯片和三个外围元件即可组成这样的一个1V转3.3V的电路图和升压电路了.可以持续稳定地供电3.3V给模块或者MCU灯电路.让后端工作稳定,同时也能控制电路的功耗. ...

  2. 你真的了解Android系统启动流程吗?Android高级工程师必看系列,已开源

    前言 从毕业到现在面试也就那么几家公司,单前几次都比较顺利,在面到第三家时都给到了我offer!前面两次找工作,没考虑到以后需要什么,自己的对未来的规划是什么,只要有份工作,工资符合自己的要求就行!所 ...

  3. shell批量解压源码包

    有时候部署环境有很多安装包,如果一个一个地解压缩实在太麻烦了,可以用shell批量进行解压缩.命令如下: [root@localhost ~]# vi tar.sh #! /bin/bash #标称是 ...

  4. The router relies on a tree structure which makes heavy use of common prefixes, it is basically a compact prefix tree (or just Radix tree).

    https://github.com/julienschmidt/httprouter/

  5. Hive语法小释

    阅读本文你可以获取: 1.数据库的查询 2.hive表的基本操作(建表三种常用方式.删除表.修改表.加载数据.内外表转换.添加分区.复制数据) 3.SQL到HiveQL的的一些不同点 1.   基本操 ...

  6. 浅析 record 使用场景

    浅析 record 使用场景 Intro 之前我们有介绍过 record 基本知识,record 会实现基于值的类型比较,最近遇到的几个问题觉得用 record 来解决会非常方便,分享一下 基于值的类 ...

  7. Hash Map集合和Hash Set集合

    HashMap集合的使用 1.1.每个集合对象的创建(new) 1.2.从集合中添加元素 1.3.从集合中取出某个元素 1.4.遍历集合 public class HashMapTest { publ ...

  8. SpringMVC听课笔记(五:处理模型数据)

    1. Spring MVC 提供了以下几种途径输出数据模型 -- ModelAndView: 处理方法返回值类型为ModelAndView 时,方法体即可通过该对象添加模型数据 -- Map及Mode ...

  9. springboot+Jenkins+docker-compose自动部署项目实践

    DevOps思想 一个开发.测试.运维的整个过程的思想. plan:需求.计划 code:编码 build:构建 test: 测试 release:发布版本 deploy:部署 operate:项目运 ...

  10. 一:整合shiro

    整合shiro 1.原生的整个 1.1 创建项目 1.2 创建Realm 1.3 配置shiro 2.使用Shiro Starter 2.1 项目创建 2.2 创建Realm 2.3 配置Shiro ...