CROC-MBTU 2012, Elimination Round (ACM-ICPC)

转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 

这场比赛整体不难。

A:直接统计,比较

B:3个部分,其中有两个地方需要注意

第三部分可能不存在,那么最后那个“/”就不需要

另外 一个就是httprururu这种情况,容易输出http://.ru/ruru,注意.ru之前是必须有的。

C:反向贪心

D:两个位的与为1,那么这两位都为1,所以把与a[i]有关的或起来

E:如果是+则加一个进来 ,如果是-则减掉一个,判断最值的差

F:就是时间的处理

G:直接暴力

struct Edge
{
    int v,next;
}e[N];
map<string,int>mp;
vector<string>name;
int start[N],tot;
void _add(int u,int v)
{
    e[tot].v=v;e[tot].next=start[u];
    start[u]=tot++;
}
void addedge(int u,int v)
{
    _add(u,v);
    _add(v,u);
}
int main()
{
    int m,cnt=0,tot=0;
    mem(start,-1);
    cin>>m;
    while(m--){
        string s1,s2;
        cin>>s1>>s2;
        if(mp.find(s1)==mp.end())
        {
            mp[s1]=cnt++;
            name.pb(s1);
        }
        if(mp.find(s2)==mp.end())
        {
            mp[s2]=cnt++;
            name.pb(s2);
        }
        int u=mp[s1],v=mp[s2];
        addedge(u,v);
    }
    cout<<cnt<<endl;
    for(int i=0;i<cnt;i++)
    {
        bool vis[N];
        mem(vis,false);
        for(int j=start[i];j!=-1;j=e[j].next) vis[e[j].v]=true;
        vis[i]=true;
        int ans=0,mmax=-1;
        for(int k=0;k<cnt;k++)
        {
            if(vis[k]) continue;
            int c=0;
            for(int j=start[k];j!=-1;j=e[j].next) if(vis[e[j].v]) c++;
            if(c>mmax)mmax=c,ans=1;
            else if(c==mmax) ans++;
        }
        cout<<name[i]<<" "<<ans<<endl;
    }
    return 0;
}

H:Dshawn比赛的时候用数状数组过了,ORZ

DP可解。

先预处理,ok[i][j]即str[i...j]是否为回文,这一步,n^2搞定。

然后sum[i][j]处理以i----j区间内,以j结尾的回文的有多少个

然后dp[i][j]表示i----j区间内的回文有多少个,就是在sum的基础上,把不以j结尾的也算上

预处理O(N^2),查询O(1)

short ok[N][N];
int ans[N][N],sum[N][N];
char str[N];
int main()
{
    while(cin>>str)
    {
        mem(ok,0);
        mem(ans,0);
        mem(sum,0);
        int l=strlen(str);
        for(int i=1;i<=l;i++)
        {
            for(int j=0;j<l-i+1;j++)
            {
                if(i==1) ok[j][j]=1;
                else if(i==2) ok[j][j+i-1]=str[j]==str[i+j-1];
                else ok[j][j+i-1]=ok[j+1][j+i-2]&&(str[j]==str[i+j-1]);
            }
        }
        for(int i=0;i<l;i++)
        {
            sum[i][i]=ok[i][i];
            for(int j=i+1;j<l;j++)  sum[i][j]=sum[i][j-1]+ok[i][j];
        }
        for(int i=0;i<l;i++)
        {
            ans[i][i]=ok[i][i];
            for(int j=i-1;j>=0;j--) ans[j][i]=ans[j+1][i]+sum[j][i];
        }
        int L,R,q;
        cin>>q;
        while(q--)
        {
            cin>>L>>R;
            L--;R--;
            cout<<ans[L][R]<<endl;
        }
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值