牛客多校第六场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 ...
随机推荐
- 微人事项目-mybatis-持久层
摘要 最近将微人事这个开源项目进行了复现,这篇文章记录mybaits访问数据库这一块. 其中MyBatis是一个流行的持久层框架,支持自定义SQL.存储过程和高级映射.MyBatis消除了几乎所有的J ...
- python(paramiko模块的简单使用)
#通过paramiko模块连接主机运行bash命令 import paramiko hostname = '192.168.88.31' port = 22 username = 'root' pas ...
- 温习数据算法—js滑块验证码
前言 大多数的应用软件都需要输入一些验证码,验证码的样式也多种多样. 比如抢票,提交订单需要验证码,很多人就纳闷了,怎么还需要验证码呢?这不是浪费时间嘛. 存在即合理,合理就是现实的. 源码下载地址+ ...
- jmeter的线程数,并发用户数,TPS,RPS 关系解说
背景 在做性能测试的时候,传统方式都是用并发虚拟用户数来衡量系统的性能(站在客户端视角),一般适用于一些网页站点例如首页.H5的压测:而RPS(Requests per second)模式主要是为了方 ...
- (Oracle)关于blob转到目标库报ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值错误解决方案
在数据抽取时,开发需要clob类型的数据,但是目标库类型是blob类型的,于是抽取的时候报错: ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值错误 可能有以下几种原因: 可能有以下 ...
- 一致性哈希算法C#实现
一致性hash实现,以下实现没有考虑多线程情况,也就是没有加锁,需要的可以自行加上.因为换行的问题,阅读不太方便,可以拷贝到本地再读. 1 /// <summary> 2 /// 一致性哈 ...
- centos7+python+selenium+chrome
1.安装chrome yum install google-chrome 2.安装chromedriver所有版本的下载地址:https://sites.google.com/a/chromium.o ...
- Azure Terraform(八)利用Azure DevOps 实现Infra资源和.NET CORE Web 应用程序的持续集成、持续部署
一,引言 上一篇讲解到利用 Azure DevOps 将整个 Azure Web App,Azure Traffic Manager profile,Azure Storage Account,Azu ...
- IP路由__距离矢量路由选择协议
矢量路由选择协议 1.距离矢量路由选择算法发送完整的路由选择表到相邻的路由器,然后,相邻的路由器会将接收到的路由表项与自己原有的路由表进行组合,以完善路由器的路由表. 由于路由器接收到的更新只是来自相 ...
- Commons Collections1分析
0x01.基础知识铺垫 接下来这个过程将涉及到几个接口和类 1.LazyMap 我们通过下⾯这⾏代码对innerMap进⾏修饰,传出的outerMap即是修饰后的Map: Map outerMap = ...