您的位置:首页 > 其它

Facebook Hacker Cup 2016 Round 2

2016-01-25 21:05 429 查看

Boomerang Decoration

处理前后缀,得到前缀和后缀染色任意长度所花的时间,然后枚举前缀和后缀染色个数取最优。

#include <bits/stdc++.h>

using namespace std;

#define ll long long

char a[100010];
char b[100010];

int suf[100010];
int pre[100010];
int sans[100010];
int pans[100010];

int main(){
int t;
cin>>t;
int cas = 0;
while(t--){
cas++;
int n;
cin>>n;
scanf("%s",a+1);
scanf("%s",b+1);

suf
=1;
pre[1]=1;
for(int i=2;i<=n;i++){
if(b[i]!=b[i-1])pre[i]=pre[i-1]+1;
else pre[i]=pre[i-1];
}
for(int i=n-1;i>=1;i--){
if(b[i]!=b[i+1])suf[i]=suf[i+1]+1;
else suf[i]=suf[i+1];
}

memset(pans,0,sizeof(pans));
memset(sans,0,sizeof(sans));

for(int i=1;i<=n;i++){
if(a[i]!=b[i]){
pans[i] = pre[i];
}else{
pans[i] = pans[i-1];
}
}
for(int i=n;i>=1;i--){
if(a[i]!=b[i]){
sans[i] = suf[i];
}else{
sans[i] = sans[i+1];
}
}

int ans = max(sans[1],pans[1]);
for(int i=1;i<n;i++){
ans = min(ans,max(sans[i+1],pans[i]));
}
printf("Case #%d: %d\n",cas,ans);
}
return 0;
}


Carnival Coins

首先根据基本概率公式计算抛任意个硬币获胜的概率(我用了对数避免精度问题)。然后dp求解最优期望。

#include <bits/stdc++.h>

using namespace std;

#define ll long long

double lg[3010];
double lgc[3010][3010];
double pp[3010];
double dp[3010];

void init(){
for(int i=0;i<=3000;i++){
pp[i] = 0;
dp[i] = 0;
}
}

int main(){
freopen("carnival_coins.txt","r",stdin);
freopen("carnival_coins.out","w",stdout);

for(int i=1;i<=3000;i++){
lg[i]=log(i);
}

for(int i=1;i<=3000;i++){
lgc[i][0] = 0;
for(int j=1;j<=i;j++){
lgc[i][j] = lgc[i][j-1]+lg[i+1-j]-lg[j];
}
}

int t;
cin>>t;
int cas = 0;
while(t--){
init();
cas++;
int n,k;
double p;
cin>>n>>k>>p;

for(int i=k;i<=n;i++){  //每次抛i个
//计算抛i个win的概率
double tmp = 0;
if(p==0){
pp[i] = 0;
}else if(p==1){
pp[i] = 1;
}else{
for(int j=k;j<=i;j++){  //抛i个,有j个向上
tmp += pow(M_E,lgc[i][j]+log(p)*j+log(1-p)*(i-j) );
}
pp[i]=tmp;
}
}

for(int i=1;i<=n;i++){
for(int j=0;j<i;j++){
dp[i] = max(dp[i],dp[j]+pp[i-j]);
}

}

printf("Case #%d: %.9f\n",cas,dp
);
}
return 0;
}


Snakes and Ladders

只有高相同的梯子,且中间没有更高的梯子隔断,才能互相挂蛇。那些可以互相挂蛇的梯子,单独拿出来,一组一组计算。我们可以先将x坐标离散化,然后给梯子排序(先高低再左右),按高低从高到低处理。成为一组首先要同高,其次不能被之前更高的梯子隔断,处理过的梯子离散化后的x坐标放入树状数组中维护,就可以迅速查询是否被阻断。

以上方法可以完成梯子的分组,同组梯子两两之间都可以挂蛇,计算花费的时候,朴素的算法复杂度是O(n2)的,会超时,通过完全平方公式,可以推出一个O(n)的计算方法。大体思路是:假设当前处理的是第i个梯子,它和上一个梯子的距离是dxi=xi−xi−1,考虑dxi作为完全平方的第二项时的展开式,递推维护好交叉项和第一项。具体见代码。

#include <bits/stdc++.h>

using namespace std;

#define ll long long

const ll mod = 1e9+7;

struct ladder{
int x;
int h;
bool operator<(const ladder &other){
if(h!=other.h){
return h>other.h;
}else{
return x<other.x;
}
}
}lads[200010];

int c[200010];

vector<int> seg;

inline int lowbit(int x){
return x&(-x);
}

void add(int x){
while(x<200010){
c[x]++;
x+=lowbit(x);
}
}

int query(int x){
int res = 0;
while(x){
res+=c[x];
x-=lowbit(x);
}
return res;
}

map<int,int> mpx;

ll ans;
void init(){
memset(c,0,sizeof(c));
mpx.clear();
ans=0;
}

vector<int> vec;

//处理同组
void work(){
int sz = seg.size();
ll tleft = 0;
ll tmid = 0;
ll tmp = 0;
for(int i=1;i<sz;i++){
ll dx = seg[i] - seg[i-1];
ll tright = (dx*dx)%mod*i%mod;
tleft = tmp;
tmp = tleft + 2*tmid*dx + tright;
tmp%=mod;
ans+=tmp;
ans%=mod;
tmid += dx*i;
tmid%=mod;
}

}

int main(){
//  freopen("snakes_and_ladders.txt","r",stdin);
//  freopen("snakes_and_ladders.out","w",stdout);
int t;
cin>>t;
int cas = 0;
while(t--){
init();
cas++;

int n;
cin>>n;

for(int i=0;i<n;i++){
scanf("%d%d",&lads[i].x,&lads[i].h);
mpx[ lads[i].x ] = 0;
}

//离散化
int kk =1;
map<int,int>::iterator it;
for(it=mpx.begin();it!=mpx.end();it++){
it->second = kk++;
}

sort(lads,lads+n);

for(int i=0;i<n;i++){
vec.push_back(lads[i].x);
if(i==n-1 || lads[i].h != lads[i+1].h){
//下面处理同高的
int sz = vec.size();
int leftMostX = mpx[vec[0]];
int start = 0;

for(int j=0;j<sz;j++){
int curX = mpx[vec[j]];
if(query(curX)!=query(leftMostX)){
work();
seg.clear();
leftMostX = curX;
start = j;
}
seg.push_back(vec[j]);
}
work();
seg.clear();
//同高的处理完了,作为障碍物插入BIT
for(int j=0;j<sz;j++){
int target = mpx[vec[j]];
add(target);
}
vec.clear();
}
}
printf("Case #%d: %I64d\n",cas,ans);
}
return 0;
}


Costly Labels

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  facebook hacker cup