题目链接:Is Today Friday?
No, it's not Friday :(
TangTang loves Friday and he has made up a list of n days which are all Friday! Each date in this list is formed as "yyyy/mm/dd", where "yyyy" is a four-digit number representing the year, "mm" is a two-digit number representing the month and "dd" is a two-digit number representing the day. TangTang only considers years between 1600 and 9999 (inclusive), so each year in the list always has four digits, but the months and the days may have leading zeros when it's necessary. For example, "August 3rd, 2019" should be formed as "2019/08/03".
To store safely, TangTang ciphered the list using a simple substitution cipher. He substituted each digit by a letter between 'A' and 'J' such that the same digits correspond to the same letter and different digits to different letters.
Unfortunately, TangTang forgot which letter corresponds to which digit. Please help him restore the original list.输入描述:
There are multiple test cases. The first line contains an integer T (1≤T≤101 \leq T \leq 101≤T≤10), indicating the number of test cases. Test cases are given in the following. For each test case, the first line contains an integer n (1≤n≤1000001 \leq n \leq 1000001≤n≤100000), indicating the number of dates. Each of the next n lines contains a string in the form of "yyyy/mm/dd", representing a ciphered date, where each digit is substituted by an uppercase letter between 'A' and 'J'.输出描述:
For each test case, output "Case #x: y" in one line (without quotes), where x indicates the case number starting from 1, and y denotes the answer to this test case. If there is no way to restore the list, then y is "Impossible". Otherwise, y is a string consisting of ten distinct digits, representing the key to decipher the list. More specifically, the i-th digit in y corresponds to the i-th uppercase letter. If there are at least two ways, then y is the smallest possible string in the lexicographical order.输入
2 1 CABJ/AI/AC 5 CABJ/AI/AC CABJ/AI/AD CABJ/AI/AE CABJ/AI/AF CABJ/AI/AG输出
Case #1: 0123456789 Case #2: Impossible
题意:
大写字母A~J分别代表数字0~9的其中一个,给你n个由字母表示的日期,他们都代表周五,找到满足条件的的对应关系,答案是字典序最小的一个
分析:
初始化为A~J对应0~9(这个是字典序最小的),然后使用 next_permutation 得到字典序从小到大的全排列,对每个排列根据蔡勒公式判定可行性
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
int n,mx,flag;
string s[maxn];
int ans[12];
int _month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
bool check(int x)
{
int year=0;
int month=ans[s[x][5]-'A']*10+ans[s[x][6]-'A'];
int day=ans[s[x][8]-'A']*10+ans[s[x][9]-'A'];
for (int i=0;i<=3;i++) year=year*10+ans[s[x][i]-'A'];
if((year%4==0 && year%100!=0) || (year%400==0)) _month[2]=29;
else _month[2]=28;
if(year<1600 || year>9999) return false;
if(month<1 || month>12) return false;
if(day<1 || day>_month[month]) return false;
if(month<=2) month+=12,year--;
int tmp=(day+month*2+3*(month+1)/5+year+year/4-year/100+year/400+1)%7;
return tmp==5;
}
void rua()
{
int ff=1;
for (int i=1;ff && i<=mx;i++) if(!check(i)) ff=0;
if(ff) for (int i=mx+1;ff && i<=n;i++) if(!check(i)) ff=0;
if(ff)
{
for (int i=0;i<10;i++) printf("%d",ans[i]);printf("\n");
flag=1;return;
}
}
int main()
{
int t;scanf("%d",&t);
for (int id=1;id<=t;id++)
{
for (int i=0;i<10;i++) ans[i]=i;
scanf("%d",&n);
for (int i=1;i<=n;i++) cin>>s[i];
sort(s+1,s+1+n);
n=unique(s+1,s+1+n)-(s+1);
mx=min(20,n);flag=0;
printf("Case #%d: ",id);
while (1)
{
rua();
if(flag) break;
if(!next_permutation(ans,ans+10)) break;
}
if(!flag) printf("Impossible\n");
}
return 0;
}

本文探讨了一道有趣的算法题目,挑战者需从一组被字母替换的日期中找出所有表示周五的日子,并还原其原始日期格式。通过分析字母与数字之间的映射关系,采用蔡勒公式验证日期的有效性,最终寻找出字典序最小的正确答案。

500

被折叠的 条评论
为什么被折叠?



