codechef 两题

时间:2023-03-09 18:33:58
codechef 两题

前面做了这场比赛,感觉题目不错,放上来。

A题目:对于数组A[],求A[U]&A[V]的最大值,因为数据弱,很多人直接排序再俩俩比较就过了。

其实这道题类似百度之星资格赛第三题XOR SUM,不过他求得是XOR最大值,原理类似。。

B:KMP居然写搓了,后来一直改,题目放个链接好了:http://www.codechef.com/LTIME14/problems/TASHIFT。

我么可以对B字符串复制一下,然后再对A字符串求出NEXT数组,再匹配的过程中求出匹配最大长度时的位置,

刚开始我没想到这种做法,然后是先求出NEXT数组,然后二分,具体看代码。CODECHEF好像不能赛后交,代码的正确性。。

 T#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
#include<list>
#define inf 0x3f3f3f
typedef long long ll;
using namespace std;
char s[];
char ss[];
int next[];
int n; void kmp()
{
int k=-,i=;
memset(next,,sizeof(next));
next[]=-;
while (i<n)
{
if (k==-||s[k]==s[i])
next[++i]=++k;
else k=next[k];
}
} int getkmp(int x)
{
int k=,i=;
while (i<(*n-)&&k<x)
{
if (k==-||ss[i]==s[k])
{
k++;i++;
}
else k=next[k];
}
if (k==x) return i-x;
return -;
} int main()
{
scanf("%d",&n);
scanf("%s%s",s,ss);
kmp();
int ans=;
for (int i=n;i<n+n-;i++) ss[i]=ss[i-n];
ss[n+n-]='\n';
int h=,t=n; for (int o=;o<;o++)
{
int mid=(h+t)/;
if (getkmp(mid)!=-) {h=mid;ans=getkmp(mid);}
else t=mid;
}
printf("%d\n",ans);
return ;
}

另外附百度之星XOR SUM的01字典树代码:

 #include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<string>
using namespace std;
#define N 3333333
int next[N][],end[N];
int pos;
void add(int cur,int k) {
next[pos][]=next[pos][]=;
end[pos]=;
next[cur][k]=pos++;
} int cal(int x)
{
int cur=;
for (int i=;i>=;i--){
int k=((<<i)&x)?:;
if (next[cur][k]) cur=next[cur][k];
else cur=next[cur][-k];
}
return end[cur];
} int main()
{
int T;
scanf("%d",&T);
for (int o=;o<=T;o++)
{
int n,m;
scanf("%d%d",&n,&m);
pos=;
memset(next[],,sizeof(next[]));
for (int i=;i<n;i++) {
int x;
scanf("%d",&x);
int cur=;
for (int j=;j>=;j--)
{
int k=;
if ((<<j)&x) k=;
if (next[cur][k]==) add(cur,k);
cur=next[cur][k];
}
end[cur]=x;
}
printf("Case #%d:\n",o);
for (int i=;i<m;i++){
int x;
scanf("%d",&x);
int ans=cal(x);
printf("%d\n",ans);
}
}
return ;
}