题目链接:https://ac.nowcoder.com/acm/contest/886/G 思路:根据题意直接模拟计算,从 0 − 9 0-9 0−9进行暴搜回溯且 c h e c k check check此时的条件下是否满足,直到找到满足条件的情况,用蔡勒公式来判断是否是星期五就 o k ok ok了,读入时不去重会超时! AC代码:
#include<bits/stdc++.h> using namespace std; int n; int flag=0; int vis[13]; int tmp[13]; char a[100010][13]; int datatoint(int m,int d,int y)//蔡勒公式 { return 1461*(y+4800+(m-14)/12)/4 +367*(m-2-(m-14)/12*12)/12 -3*((y+4900+(m-14)/12)/100)/4 +d-32075; } int check() { for(int i=0;i<n;i++){ int y=0,m=0,d=0; for(int j=0;j<=3;j++){ y=y*10+tmp[a[i][j]-'A']; } for(int j=5;j<=6;j++){ m=m*10+tmp[a[i][j]-'A']; } for(int j=8;j<=9;j++){ d=d*10+tmp[a[i][j]-'A']; } if(y<1600||m>12||d>31){ return 0; } if((m==4||m==6||m==9||m==11)&&d>30){ return 0; } int c=28; if(y%400==0||(y%4==0&&y%100!=0)){ c+=1; } if(m==2&&d>c){ return 0; } int tm=datatoint(m,d,y)+1; //cout<<tm%7<<endl; if(tm%7!=5){//判断不是周五 return 0; } } return 1; } void dfs(int d) { if(d>=10){ flag=check(); return ; } for(int i=0;i<10;i++){ if(!vis[i]){ vis[i]=1; tmp[d]=i; dfs(d+1); vis[i]=0;//暴搜回溯 if(flag){ return ; } } } } int main() { int t; scanf("%d",&t); for(int k=1;k<=t;k++){ for(int i=0;i<10;i++){ vis[i]=0; tmp[i]=0; } flag=0; scanf("%d\n",&n); for(int i=0;i<n;i++){ scanf("%s",&a[i]); if(i>0&&strcmp(a[i],a[i-1])==0){//不去重会超时 i--; n--; } } dfs(0);//从0开始暴搜 printf("Case #%d: ",k); if(flag){ for(int i=0;i<10;i++){ printf("%d",tmp[i]); } printf("\n"); } else { printf("Impossible\n"); } } return 0; }