您的位置:首页 > 其它

VK Cup 2012 Qualification Round 2部分题解(C,D,E)

2012-03-13 01:15 363 查看
CF上的一场资格赛,有二十四小时的时间给我们做,所以为了晋级,我和队友合力弄掉了四题,而最后的E题其实也不难,后来也过了……因为A,B相对较水,所以以下只讲后三题……

contest

C题:

比赛时一致认为暴力不行,比赛后发现很多都是暴力过的……因此,比赛时用到了树状数组……其实是队友做出的,无限YM……不过树状数组真是个好东西啊……

#include<iostream>
#include<cstring>
#include<string>
using namespace std;
#define M (1<<18)
int cl[26][M];             //cl[i][j]表示的是第i种字母在数高为j里的数目
int lowbit(int x)
{
return x&(-x);
}
void add(int id,int pos,int v)
{
while(pos<M)
{
cl[id][pos]+=v;
pos+=lowbit(pos);
}
}
int find(int id,int x)
{
int i,ans,cnt;
ans=cnt=0;
for(i=18;i>=0;i--)
{
ans+=(1<<i);
if(ans>=M||cnt+cl[id][ans]>=x)ans-=(1<<i);
else cnt+=cl[id][ans];
}
return ans+1;
}
int main()
{
//freopen("a.txt","r",stdin);
int i,k,n,x,id,pos,len;
char c;
string s,str;
cin>>n>>s;
str="#";
for(i=0;i<n;i++)str+=s;
len=str.size();
for(i=1;i<len;i++)
{
id=str[i]-'a';
add(id,i,1);             //建树
}
cin>>k;
while(k--)
{
cin>>x>>c;
id=c-'a';
pos=find(id,x);             //找此点目前的位置
str[pos]='#';
add(id,pos,-1);             //删点
}
for(i=0;i<len;i++)
{
if(str[i]=='#')continue;
cout<<str[i];
}
cout<<endl;
return 0;
}


D题:

这题是一道挺好的dp,里面的数组f[i][j]表示的是字符串i到j的回文的数目,sum[i]表示的是i后面(包括i)的回文的数目……

#include<iostream>
using namespace std;
__int64 f[2005][2005];
int main()
{
//freopen("a.txt","r",stdin);
__int64 i,j,k,l,len,sum[2005];
char s[2005];
scanf("%s",s);
len=strlen(s);
memset(f,0,sizeof(f));
for(i=0;i<len;i++)f[i][i]=1;             //只有一个字符时,回文数为1
for(i=1;i<len;i++)             //i表示间距
for(j=0;i+j<len;j++)
{
k=i+j;
if(s[j]==s[k])
{
if(i==1)f[j][k]=1;
else f[j][k]=f[j+1][k-1];             //只有j和k中间的那一段是回文,j到k才是回文
}
}
memset(sum,0,sizeof(sum));
for(i=0;i<len;i++)
for(j=i;j<len;j++)
sum[i]+=f[i][j];             //这时sum[i]以i为起点的后面的回文数
for(i=0;i<len;i++)
for(j=i+1;j<len;j++)
sum[i]+=sum[j];             //这里sum[i]加上i后面不同起点的回文数
l=0;
for(i=0;i<len;i++)
for(j=i;j<len;j++)
if(f[i][j])l+=sum[j+1];
printf("%I64d\n",l);
return 0;
}


E题:

超级模拟题,不多说,直接看代码……

#pragma warning(disable:4786)
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<map>
using namespace std;
struct T
{
int c,d;
__int64 h;
}p[100005];
bool cmp(T x,T y)
{
return x.c!=y.c?x.c<y.c:x.h>y.h;
}
__int64 h1[100005],h2[100005],a2[100005];
vector<int> g,a1[100005];
vector<T> v[100005];
map<int,int> m;
int main()
{
//freopen("a.txt","r",stdin);
int d,i,j,k,l,s,n,y1,y2,len,i1,j1,y3,y4;
__int64 w,x1,x2,Max;
T t;
m.clear();
scanf("%d",&n);
for(i=0;i<n;i++)v[i].clear();
for(i=0;i<n;i++)
{
scanf("%d%I64d",&p[i].c,&p[i].h);
p[i].d=i+1;
}
sort(p,p+n,cmp);
d=p[0].c;
l=1;
m[d]=l++;
for(i=1;i<n;i++)
if(p[i].c!=d)
{
d=p[i].c;
if(!m[d])m[d]=l++;
}
for(i=0;i<n;i++)
{
d=m[p[i].c];
w=p[i].h;
if(v[d].size())w+=v[d][v[d].size()-1].h;
t.h=w,t.d=p[i].d;
v[d].push_back(t);
}
len=0;
memset(h1,0,sizeof(h1));
memset(h2,0,sizeof(h2));
for(i=1;i<l;i++)
{
for(j=0;j<v[i].size();j++)
{
if(h1[j+1]<=v[i][j].h)
{
if(h1[j+1]==v[i][j].h)
{
a1[j+1].push_back(i);
continue;
}
if(a1[j+1].size())
{
h2[j+1]=h1[j+1];
a2[j+1]=a1[j+1][0];
}
h1[j+1]=v[i][j].h;
a1[j+1].clear();
a1[j+1].push_back(i);
}
else
{
if(h2[j+1]<v[i][j].h)
{
h2[j+1]=v[i][j].h;
a2[j+1]=i;
}
}
}
if(len<v[i].size())len=v[i].size();
}
Max=0;
for(i=1;i<=len;i++)
{
x1=h1[i];
for(j=i-1;j<i+2;j++)
{
if(j==0||j==len+1)continue;
x2=h1[j];
for(k=0;k<a1[i].size();k++)
{
y1=a1[i][k];
for(l=0;l<a1[j].size();l++)
{
y2=a1[j][l];
if(y1!=y2)break;
}
if(l!=a1[j].size())break;
}
if(k==a1[i].size())
{
x2=h2[j];
y2=a2[j];
}
if(x2==0)continue;
if(Max<x1+x2)
{
Max=x1+x2;
s=i+j;
i1=i,j1=j,y3=y1,y4=y2;
}
}
}
g.clear();
d=i1<j1?i1:j1;
if(i1<j1)swap(y3,y4);
for(i=0;i<d;i++)
{
g.push_back(v[y3][i].d);
g.push_back(v[y4][i].d);
}
if(i1!=j1)g.push_back(v[y3][i].d);
printf("%I64d\n%d\n",Max,s);
for(i=0;i<g.size();i++)
{
if(i)printf(" ");
printf("%d",g[i]);
}
printf("\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: