codechef July Challenge 2014

   A题: Count Substrings

  水题一枚,只需知道有多少个1就行了,假设有x个1,最后答案就是从x个1中选2个1的组合数加上x,因为定义了

s[i]到s[i]也算一个序列。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define sf scanf
#define pf printf
using namespace std;
const int N=5+1e5;
char s[N];
int main()
{
    int T;
    int i,n;
    sf("%d",&T);
    while(T--)
    {
        sf("%d",&n);
        sf("%s",s);
        long long  cnt=0;
        for(i=0;i<n;i++)
            if(s[i]=='1')
                cnt++;
        pf("%lld\n",cnt+cnt*(cnt-1)/2);
    }
    return 0;
}

B题: Reach The Point

  题目意思要理解清楚,人只能左或右转再走一步,所以在坐标纸上分析的时候只能走折线,另外要区别坐标是在

y=x直线的上方还是下方,总之自己在坐标纸上模拟一下怎么走(4,2)和(2,4)点,你就会找出规律了。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define sf scanf
#define pf printf
using namespace std;
typedef long long LL;
LL SB(LL n){
  return n>0?n:(-n);
}
int main()
{
    int T;
    long long x,y,N,M;
    long long ans=0;
    sf("%d",&T);
    while(T--)
    {
       sf("%lld%lld",&x,&y);
        x=SB(x),y=SB(y);
        M=min(x,y),N=max(x,y);
        ans=2*M;
        if(x>=y)
         ans+=(N-M)%2==0?(N-M)/2*4:(3+(N-M)/2*4);
        else  ans+=(N-M)%2==0?(N-M)/2*4:(1+(N-M)/2*4);
       pf("%lld\n",ans);
    }
    return 0;
}

C题: Chef and Frogs

  好题,值得一做,普通方法肯定会TLE,所以用了一种比较奇葩的树状数组,也不枉学了几天的数据结构吧。

大致思路就是先排一遍序,记录下每个数初始的位置在排序后是那个位置,储存在loc数组中,在询问的时候,

把位置a,b转换为在排序后的数组中的位置,这样就可以直接对排序后的数组进行查询了,具体查询就是用比较快的

树状数组实现的,那么具体怎么跟树状数组扯上的呢?对于每个位置,若它与前一个位置的差小于等于K,就更新为1,否则该位置还是保持为0,所以这样一直更新下来,对于每一个询问(a,b),看区间内的数是否全为1,即

read(b)-read(a-1)==b-a+1?等于则是yes,否则还要判断一下,具体见代码:

希望有人交流一下更好的做法。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define sf scanf
#define pf printf
using namespace std;
const int N=5+1e5;
typedef struct node
{
    int id,val;
}node;
node po[N];
bool bk[N];
int n,loc[N],tree[N];
int read(int pos){
  int ans=0;
  while(pos>0)
  {
      ans+=tree[pos];
      pos-=pos&-pos;
  }
  return ans;
}
void update(int pos,int val){
  while(pos<=n)
  {
      tree[pos]+=val;
      pos+=pos&-pos;
  }
}
bool cmp(node a,node b)
{
    return a.val<b.val;
}
int main()
{
    int k,p,a,b,i;
    sf("%d%d%d",&n,&k,&p);
    for(i=1;i<=n;i++)
    {
        sf("%d",&po[i].val);
        po[i].id=i;
    }
    sort(po+1,po+1+n,cmp);
    memset(tree,0,sizeof(tree));
    memset(bk,0,sizeof(bk));
    for(i=1;i<=n;i++)   loc[po[i].id]=i;
    update(1,1);
    for(i=2;i<=n;i++)
     if(po[i].val-po[i-1].val<=k)
            bk[i]=1,update(i,1);
    while(p--)
    {
        sf("%d%d",&a,&b);
        a=loc[a],b=loc[b];
        if(a>b)  swap(a,b);
        if(read(b)-read(a-1)==b-a+1)  pf("Yes\n");
        else
        {
            if(!bk[a]&&read(b)-read(a)==b-a) pf("Yes\n");
            else  pf("No\n");
        }
    }
    return 0;
}

E题:Dish Owner

  模板简单并查集

直接上代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define sf scanf
#define pf printf
using namespace std;
const int N=5+1e4;
int s[N],fa[N];
int root(int x){
    if(x==fa[x]) return x;
    else  return fa[x]=root(fa[x]);
}
int main()
{
    int T,Q,n,x,y,i,type;
    sf("%d",&T);
    while(T--)
    {
        sf("%d",&n);
        for(i=1;i<=n;i++)  sf("%d",&s[i]),fa[i]=i;
        sf("%d",&Q);
        while(Q--)
        {
            sf("%d",&type);
            if(!type){
                sf("%d%d",&x,&y);
                int tx=root(x),ty=root(y);
                if(tx==ty)  pf("Invalid query!\n");
                else if(s[tx]>s[ty]) fa[ty]=tx;
                else if(s[tx]<s[ty]) fa[tx]=ty;
                else continue;
            }
            else{
                sf("%d",&x);
                pf("%d\n",root(x));
            }
        }
    }
    return 0;
}


后面的题随后更新:::



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值