2019牛客多校第六场——G.Is Today Friday?【数学/蔡勒公式】

题目链接: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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值