您的位置:首页 > 大数据 > 人工智能

2013 Multi-University Training Contest 8 小结

2013-08-17 20:31 302 查看
        前天做多校,做的很差,一直都是没怎么认真想题就去做或者就是感觉一看是树形dp就觉得很难,然后就没有认真去分析,心里感觉那样的题我肯定也写不出来,但是今天真的心平气和的做的时候发现也不难。。。。

         想起来多校的第五场,有一道kmp的变形题,我分析了一半,然后和强神又分析了下,其实思路就和题解上是一样的了,但是却没有写:第一:感觉不好写,不知道怎么去写,写了也不一定可以写出来,第二:那题过的也就是那几个队,如果我们分析出来的话那些大牛学校也应该分析出来了,所以应该是错的吧,所以分析了那么多程序却是一个字都没有写的。比赛结束后我还在找这方面那方面的原因,最后强神说的一句话我觉得很好,就是没有自信,不敢去写,怕写错,不相信自己!!!!!

         前天比赛,我做了第六题,不知道当时激动什么,连最基本的打表都忘了,想着那么多学校都过了,应该就可以暴力的,结果来了一个一点弯都没有拐的暴力,果断的TLE了,第四题的树形dp,也有点思路,但是没有深入去分析,一直觉得树形dp可难(心里作用),而且想着这些题钢牛是强项,也不用我去写,然后就没有然后了。。。第十题,最大二分匹配又加了点条件,想到的是建图然后求强连通分量,但是思路不怎么成熟,没有想到去虚拟王子和公主,然后就直接求联通分量了,然后就是自己找数据的时候发现了各种bug,然后一直WA,到最后就只想到了求强连通分量的思路可能是错的,没有进一步在此基础上去深入,贡献了无数的wa啊!第三题是博弈题,我一看了一眼图就让强神去看了,我的博弈真的是差,到现在都一道博弈题靠自己的力量写出来的都没有,然后强神奋战了几乎一下午,贡献了无数的RE和WA,也没有过,然后后来看了题解,他说他都分析出来了,只是什么与写错了。。。钢牛整场都在奋战第九题,方神回家了,然后整场比赛的结果,唉,说多了都是泪啊!

      暑假过的好快,集训也快要结束了,然后感觉整个刷题的过程学东西可慢了,但是还是学会了不少,我感觉应该在比赛中多多总结经验,不然比赛因为一时失误将会做的题没做出来,那就亏大了啊!

     今天将前天比赛的我集中分析的三道题写了一遍,感觉自己分析的思路总是差了那么一点点,然后就是过不去,我想什么时候给那个一点点给过去了,那应该是很大的提高吧! 还有一点就是平时训练的时候很懒散,算法想出来的时候但是写的时候总是晃晃悠悠的,没有一点时间观念,然后就导致比赛写题的时候敲代码花了好长时间,一定要改啊!

    然后的然后,将我写的三道题代码贴出来好了,还有一道自己度错题WA了n次啊!!!!O_O

hdoj 4679

/////////////////////////////////////////////////////////////////////////
// File Name: 4679.cpp
// Author: wang
// mail:
// Created Time: 2013-8-17 14:55:24
/////////////////////////////////////////////////////////////////////////
#pragma comment(linker, "/STACK:102400000,102400000")
#include <cstdio>
#include <cstdlib>
#include <climits>
#include <cstring>
#include <cmath>

#include <algorithm>
#include<iostream>
#include<queue>
#include <map>
using namespace std;
typedef long long ll;
#define INF (INT_MAX/10)
#define SQR(x) ((x)*(x))
#define rep(i, n) for (int i=0; i<(n); ++i)
#define repf(i, a, b) for (int i=(a); i<=(b); ++i)
#define repd(i, a, b) for (int i=(a); i>=(b); --i)
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define N 210000

int h[N],f[N];//h[y]指的是子树中的最大直径的
int pre[N];
int n,len;
int dis[N];
int Max,sign;
struct node{
int y,w,pre,sign;
};
node a[N];
int fir[N][3];
int firp[N][3];//最大,次大和次大大

void init()
{
memset(pre,-1,sizeof(pre));
len=1;
memset(h,0,sizeof(h));
memset(f,0,sizeof(f));
memset(fir,0,sizeof(fir));
memset(firp,-1,sizeof(firp));
memset(dis,0,sizeof(dis));
}

void addpage(int x,int y,int w,int z)
{
a[len].sign=z;
a[len].y=y;
a[len].w=w;
a[len].pre=pre[x];
pre[x]=len++;
}

void dfs(int x,int fa)//最大的肯定得有的
{
for(int i=pre[x]; i!=-1; i=a[i].pre)
{
int y=a[i].y;
if(y==fa) continue;
dfs(y,x); //从上面下来的
rep(j,3)//更新的
            if(fir[y][0]+a[i].w>fir[x][j])
{
repd(k,2,j+1)//-1也是这样传递的
fir[x][k]=fir[x][k-1],
firp[x][k]=firp[x][k-1];
fir[x][j]=fir[y][0]+1;//y的最大的子跟+1;
firp[x][j]=y;
break;
}
}
h[x]=fir[x][0]+fir[x][1];//指的是最大的
}

void ddfs(int x,int fa)
{
//fa的dis怎么维护的????
    for(int i=pre[x]; i!=-1; i=a[i].pre)
{
int y=a[i].y;//删除以y为跟的子树的
        if(y==fa) continue;
int m=0;
rep(j,3)//x子树中另外的最大的,
        {
if(firp[x][j]!=y)
{
f[y]+=fir[x][j],m++;
dis[y]=max(dis[y],fir[x][j]+1);//求出y以上的最大值的
            }
if(m==2) break;
}
dis[y]=max(dis[y],dis[x]+1);//有可能是上面的承接下来的
rep(j,3)
if(firp[x][j]!=y)
{
f[y]=max(f[y],fir[x][j]+dis[x]);
break;
}
//x中的最大的
f[y]=max(f[y],f[x]);//去掉x时的最大的
        for(int k=pre[x]; k!=-1; k=a[k].pre)//x的其它子节点中的最大的
        {
if(a[k].y!=fa && a[k].y!=y)
{
f[y]=max(f[y],h[a[k].y]);//兄弟子树中的最大值的
            }
}
ddfs(y,x);
}
}
void ans(int x,int fa)
{
for(int i=pre[x]; i!=-1; i=a[i].pre)
{
int y=a[i].y;
if(y==fa) continue;
int m=a[i].w*max(h[y],f[y]);
if(m<Max)
{
Max=m;
sign=a[i].sign;
}
else if(m==Max && a[i].sign<sign)
sign=a[i].sign;
ans(y,x);
}
}
int main()
{
int test;
scanf("%d",&test);
int x,y,z;
repf(ror,1,test)
{
init();
scanf("%d",&n);
rep(i,n-1)
{
scanf("%d%d%d",&x,&y,&z);
addpage(x,y,z,i+1);
addpage(y,x,z,i+1);
}
dfs(1,-1);//求出x为跟的子树中的最大的直径的
//去掉以x为跟的子树后的最大直径f
;
f[1]=0;
dis[1]=0;
ddfs(1,-1);//默认1为整棵树的跟的
//        repf(i,1,n) cout<<h[i]<<" "; cout<<endl;
//        repf(i,1,n) cout<<f[i]<<" "; cout<<endl;
//        repf(i,1,n) cout<<dis[i]<<" "; cout<<endl;
Max=INT_MAX;
ans(1,-1);
printf("Case #%d: %d\n",ror,sign);
}
return 0;
}

 

hdoj  4681 

String

/////////////////////////////////////////////////////////////////////////
// File Name: t.cpp
// Author: wang
// mail:
// Created Time: 2013-8-15 12:38:36
/////////////////////////////////////////////////////////////////////////
#include <cstdio>
#include <cstdlib>
#include <climits>
#include <cstring>
#include <cmath>

#include <algorithm>
#include<iostream>
#include<queue>
#include <map>
using namespace std;
typedef long long ll;
#define INF (INT_MAX/10)
#define SQR(x) ((x)*(x))
#define rep(i, n) for (int i=0; i<(n); ++i)
#define repf(i, a, b) for (int i=(a); i<=(b); ++i)
#define repd(i, a, b) for (int i=(a); i>=(b); --i)
#define clr(ar,val) memset(ar, val, sizeof(ar))
#define N 1010
char a[N],b[N],c[N];
int dp[N][N];
int dp2[N][N];
int n,m;
struct node{
int l,r;
};
node aa[N*10],bb[N*10];

void fun()
{
n=0;
int lena=strlen(a),len=strlen(c);
rep(i,lena)
{
if(a[i]==c[0])
{
aa[n].l=i;
int     k=0;
repf(j,i,lena-1)
{
if(a[j]==c[k])
{
k++;
if(k==len)
{
aa[n++].r=j;
break;
}
}
}
}
}
return ;
}

void fun1()
{
m=0;
int lenb=strlen(b),len=strlen(c);
rep(i,lenb)
{
if(b[i]==c[0])
{
bb[m].l=i;
int k=0;
repf(j,i,lenb-1)
{
if(b[j]==c[k])
{
k++;
if(k==len)
{
bb[m++].r=j;
break;
}
}
}
}
}
return ;
}

void work()
{
memset(dp,0,sizeof(dp));
int lena=strlen(a),lenb=strlen(b);
rep(i,lena)
rep(j,lenb)
if(a[i]==b[j])
dp[i+1][j+1]=max(dp[i][j]+1,max(dp[i+1][j],dp[i][j+1]));
else
dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
//    rep(i,lena+1){
//        rep(j,lenb+1)
//            cout<<dp[i][j]<<" "; cout<<endl;}cout<<endl;
memset(dp2,0,sizeof(dp2));
repd(i,lena-1,0)
repd(j,lenb-1,0)
if(a[i]==b[j])
dp2[i][j]=dp2[i+1][j+1]+1;
else dp2[i][j]=max(dp2[i+1][j],dp2[i][j+1]);
//    repd(i,lena-1,0){
//        repd(j,lenb-1,0)
//            cout<<dp2[i][j]<<" "; cout<<endl;}
}

int main()
{
int test;
scanf("%d",&test);
getchar();
repf(ror,1,test)
{
// scanf("%s%s%s",a,b,c);
gets(a); gets(b); gets(c);
fun();
fun1();
int Max=0;
work();
int lena=strlen(a);
int lenb=strlen(b);
//        cout<<n<<" "<<m<<endl;
rep(i,n)
rep(j,m)
{
//                cout<<aa[i].l<<" "<<aa[i].r<<" "<<bb[j].l<<" "<<bb[j].r<<endl;
//                cout<<dp[aa[i].l][bb[j].l]<<" "<<dp[lena][lenb]<<" "<<dp[aa[i].r+1][bb[j].r+1]<<endl;
Max=max(Max,dp[aa[i].l][bb[j].l]+dp2[aa[i].r+1][bb[j].r+1]);
}
printf("Case #%d: %d\n",ror,Max+strlen(c));
}
return 0;
}
1010

Prince and Princess

/////////////////////////////////////////////////////////////////////////

// File Name: 4685.cpp

// Author: wang

// mail:

// Created Time: 2013-8-17 10:18:33

/////////////////////////////////////////////////////////////////////////
#include <cstdio>

#include <cstdlib>

#include <climits>

#include <cstring>

#include <cmath>

#include <algorithm>

#include<iostream>

#include<queue>

#include <map>
using namespace std;

typedef long long
ll;

#define INF (INT_MAX/10)

#define SQR(x) ((x)*(x))

#define rep(i, n) for (int i=0; i<(n); ++i)

#define repf(i, a, b) for (int i=(a); i<=(b); ++i)

#define repd(i, a, b) for (int i=(a); i>=(b); --i)

#define clr(ar,val) memset(ar, val, sizeof(ar))

#define N 2005//增加公主或者王子的饿个数可以很大的
int n,m;

bool
vis[N];

int
ans[N];

class
ring{

    public:

    int
len,tot,ror,col;

    int
dfn[N],low[N],pre[N];

    int
stage[N];

    bool
mark[N];

    int
Stack[N];

    struct
node{

        int
y,pre;

    };


    node a[N*1001];

    void
init()

    {


        len=1; col=0;
tot=1; ror=1;

        memset(dfn,0,sizeof(dfn));

        memset(pre,-1,sizeof(pre));

        memset(mark,false,sizeof(mark));

        memset(stage,0,sizeof(stage));

    }

    void
addpage(int s,int t)

    {


//        cout<<s<<" "<<t<<endl;
        a[len].y=t;

        a[len].pre=pre[s];

        pre[s]=len++;

    }

    void
dfs(int x)

    {


       Stack[ror++]=x;

       dfn[x]=low[x]=tot++;

       mark[x]=true;

       for(int
i=pre[x];
i!=-1; i=a[i].pre)

       {

          int
y=a[i].y;

          if(!
dfn[y])

          {


             dfs(y);

             low[x]=min(low[x],low[y]);

          }else if(
mark[y]==true)

             low[x]=min(low[x],dfn[y]);

        }

        int
i;

        if(
dfn[x]==low[x])

        {

           ++
col;

           do{


               i=Stack[--ror];

               mark[i]=false;

               stage[i]=col

            }while(
i!=x);

        }

}   

};


ring ri;

class
match{

    public:


    vector<int>vec[N];

    bool
vis[N];

    int
n,k;

    int
next[N];

    void
init()

    {


        rep(i,N) vec[i].clear();//清空的
        memset(next,-1,sizeof(next));

    }

    bool
find(int t)

    {


        rep(i,vec[t].size())

        {

            int
m=vec[t][i];

            if(
vis[m]==false)

            {


                vis[m]=true;

                if(
next[m]==-1
||
find(next[m]))

                {


                    next[m]=t;

                    return
true;

                }

            }

        }

        return
false;

    }

    int
sum()//求的是最大匹配数的
    {

        int
m=0;

        rep(i,n)

        {


            memset(vis,false,sizeof(vis));

            if(
find(i))

                m++;

        }

        return
m;

    }

};


match ma;

void
solve()

{

    int
l,x;

    ma.n=n;

    ma.init();

    rep(i,n)

    {


       scanf("%d",&l);

       while(
l--)

           scanf("%d",&x),ma.vec[i].push_back(x-1);//减去1的
    }

    ma.sum();//最大匹配的
    memset(vis,false,sizeof(vis));

    rep(i,m)//m个公主的
        if(ma.next[i]==-1)//没有匹配的
        {//增加一个王子的
            ma.next[i]=n;

        //    ma.vec
.clear();//增加之前先清空的
            rep(j,m) ma.vec[n].push_back(j);//王子喜爱每一位公主的
            vis[n]=true;

            n++;

        }

        else
vis[ma.next[i]]=true;

    rep(i,n)

        if(
vis[i]==false)//该王子没有被匹配的
        {//增加一位公主的
             ma.next[m]=i;//增加一位公主的
             rep(j,n) ma.vec[j].push_back(m);//每位王子都爱这个公主的
             m++;

        }

}

void
work()

{


     ri.init();

     rep(i,n)

         rep(j,ma.vec[i].size())

            ri.addpage(i,ma.vec[i][j]+n);//加边的
     rep(i,m)

         ri.addpage(i+n,ma.next[i]);

     rep(i,n+m)

         if(
ri.dfn[i]==0) 
ri.dfs(i);//求强连通的
}

int main()

{

    int
test;

    scanf("%d",&test);

    int
nn,mm;

    repf(ror,1,test)

    {


        scanf("%d%d",&n,&m);

        nn=n; mm=m;

        solve();//最大匹配并进行添加的
        work();//求强连通分量的额

//        rep(i,n+m) cout<<ri.stage[i]<<endl;
        printf("Case #%d:\n",ror);

        rep(i,nn)

        {


            ans[0]=0;

            for(int
j=ri.pre[i];
j!=-1; j=ri.a[j].pre)//可以匹配的
            {

                int
y=ri.a[j].y-n;

                if(
y<mm && ri.stage[i]==ri.stage[y+n])

                    ans[++ans[0]]=y;

            }


            printf("%d",ans[0]);

            sort(ans+1,ans+1+ans[0]);

            repf(j,1,ans[0])

                printf(" %d",ans[j]+1);

            printf("\n");

        }

    }

    return
0;

}


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