牛客练习赛37
练习赛地址:牛客练习赛37
A.筱玛的快乐
1.1题意
一个日期是“快乐”的,当且仅当这一年的年份是一个质数,且将月份、日期写成"MM-DD"的形式后是对称的。如:"2003-01-10"是“快乐”的。求解2000-01-01后第K个快乐日期。
1.2分析
由于查询次数不大于1e6,会大规模查询,所以肯定要进行预处理打表,由于一年内对称的只有6个,所以只需要用素数筛标记处范围内的所有素数的年份即可。
1.3代码
1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 using namespace std; 5 const int MAXN = 1e6+2005; 6 int h[MAXN],Y[MAXN]; 7 int n,k; 8 void Init() 9 { 10 memset(h,0,sizeof(h)); 11 for(int i=2;i<=MAXN;i++) 12 if(!h[i]) 13 for(int j=i+i;j<=MAXN;j+=i) 14 h[j]=1; 15 int cnt = 0; 16 for(int i=2000;i<MAXN;i++) 17 if(!h[i]) 18 Y[cnt++] = i; 19 } 20 void Solve() 21 { 22 int y = ((k-1)/6)+1; 23 int d = (k-1)%6; 24 int cnt = 0; 25 printf("%d",Y[y-1]); 26 if(d==0) printf("-01-10\n"); 27 if(d==1) printf("-02-20\n"); 28 if(d==2) printf("-03-30\n"); 29 if(d==3) printf("-10-01\n"); 30 if(d==4) printf("-11-11\n"); 31 if(d==5) printf("-12-21\n"); 32 } 33 int main() 34 { 35 Init(); 36 while(scanf("%d",&n)!=EOF) 37 { 38 for(int i=0;i<n;i++) 39 { 40 scanf("%d",&k); 41 Solve(); 42 } 43 } 44 return 0; 45 }
C.筱玛的迷阵探险
2.1题意
给出一个矩阵A与初始经验值e,初始位置在矩阵左上角,终点在矩阵右下角,从起点到终点的移动过程中只能向下向右移动,最后能获得的经验值为初始经验与路径上经过的所有数的权值异或和。求解最大的经验。
2.2.分析
首先,“最后能获得的经验值为初始经验与路径上经过的所有数的权值异或和”的意思是
$su{m_0} = e$, $sum' = sum \wedge A[i][j]$
很容易想到的一种思路是在矩阵上跑一个dfs:
1 # include <iostream> 2 # include <cstdio> 3 using namespace std; 4 const int maxn = 25; 5 int Map[maxn][maxn]; 6 int n,e,ans; 7 void Init() 8 { 9 for(int i=0;i<n;i++) 10 for(int j=0;j<n;j++) 11 scanf("%d",&Map[i][j]); 12 } 13 void dfs(int dx,int dy,int sum) 14 { 15 if(dx==n-1&&dy==n-1) 16 { 17 ans = max(ans,sum); 18 return; 19 } 20 if(dx+1<n) 21 dfs(dx+1,dy,sum^Map[dx+1][dy]); 22 if(dy+1<n) 23 dfs(dx,dy+1,sum^Map[dx][dy+1]); 24 } 25 void Solve() 26 { 27 ans = -1; 28 dfs(0,0,e); 29 printf("%d\n",ans); 30 } 31 int main() 32 { 33 while(scanf("%d%d",&n,&e)!=EOF) 34 { 35 Init(); 36 Solve(); 37 } 38 return 0; 39 }
但是注意到,矩阵尺寸$n \le 20$,所以常规的dfs很容易超时,所以这里使用折半搜索: