[置顶] 2013 Multi-University Training Contest 8

1003 Mine

简单sg的博弈题,我们走入了nim博弈的误区,后来发现改了三四个字符就过了。。。。我只能说我是sbsbsbsbsbsb。。。判奇偶啊。。。

 

#pragma comment(linker,"/STACK:102400000,102400000")//用的是dfs搜索,写得挫,不加上这个且用C++交就跪了。。

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<string>

#include<cmath>

#include<set>

#include<vector>

#define mem(a,b) memset(a,b,sizeof(a))

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

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

#define N 9973

using namespace std;

inline void RD(int &ret)

{

    char c;

    do

    {

        c=getchar();

    }

    while(c<'0'||c>'9');

    ret=c-'0';

    while((c=getchar())>='0'&&c<='9')

    {

        ret=ret*10+(c-'0');

    }

}

inline void OT(int a)

{

    if(a>=10)

    {

        OT(a/10);

    }

    putchar(a%10+'0');

}

int n,m,k;

int sum[1005][1005];

int used[1005][1005];

int s[1000005];

int shu,shuk,ans;

int dx[9]={-1,-1,-1,0,0,1,1,1};

int dy[9]={-1,0,1,-1,1,-1,0,1};

void dfs(int x,int y)//用的就是施教主写的

{//这里的目的就是求空白部分周围的数字块数量

    int i;

    used[x][y]=1;

    for(i=0;i<8;i++)

    {

        if(x+dx[i]>=0&&x+dx[i]<n&&y+dy[i]>=0&&y+dy[i]<m)

        {

            if(used[x+dx[i]][y+dy[i]]==0&&sum[x+dx[i]][y+dy[i]]==0)

            {

                dfs(x+dx[i],y+dy[i]);

            }

        }

    }

    for(i=0; i<8; i++)

    {

        if(x+dx[i]>=0&&x+dx[i]<n&&y+dy[i]>=0&&y+dy[i]<m)

        {

            if(used[x+dx[i]][y+dy[i]]==0&&sum[x+dx[i]][y+dy[i]]>0)

            {

                used[x+dx[i]][y+dy[i]]=1;

                shuk++;

            }

        }

    }

}

int main()

{

    int t,cas,i,j,a,b;

    while(scanf("%d",&t)!=EOF)

    {

        cas=0;

        while(t--)

        {

            cas++;

            RD(n);

            RD(m);

            RD(k);

            for(i=0; i<n; i++)

            {

                for(j=0; j<m; j++)

                {

                    sum[i][j]=0;

                    used[i][j]=0;

                }

            }

            for(i=0; i<k; i++)

            {

                RD(a);

                RD(b);

                for(j=0; j<8; j++)

                {

                    if(a+dx[j]>=0&&a+dx[j]<n&&b+dy[j]>=0&&b+dy[j]<m)

                    {

                        sum[a+dx[j]][b+dy[j]]++;

                    }

                }

                used[a][b]=1;

            }

            shu=0;

            for(i=0; i<n; i++)

            {

                for(j=0; j<m;j++)

                {

                    if(used[i][j]==0)

                    {

                        if(sum[i][j]==0)//判奇偶,如果为奇数算作两块,偶数为一块

                        {

                            shuk=0;

                            dfs(i,j);

                            s[shu]=shuk%2+1;//就这里改了一下就AC了,哭啊

                            shu++;

                        }

                    }

                }

            }

            for(i=0; i<n; i++)

            {

                for(j=0; j<m; j++)

                {

                    if(used[i][j]==0)//其它单独数字块各为1块

                    {

                        s[shu]=1;

                        shu++;

                    }

                }

            }

            ans=0;

            for(i=0;i<shu;i++)

            {

                ans^=s[i];//异或一下就行了

            }

            printf("Case #%d: ",cas);

            if(ans!=0)

            {

                printf("Xiemao\n");

            }

            else

            {

                printf("Fanglaoshi\n");

            }

        }

    }

    return 0;

}


1006 String

 

一道求最长公共子串的水题。。。

 

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<string>

#include<cmath>

#define mem(a,b) memset(a,b,sizeof(a))

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

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

using namespace std;

inline void RD(int &ret)

{

    char c;

    do

    {

        c=getchar();

    }

    while(c<'0'||c>'9');

    ret=c-'0';

    while((c=getchar())>='0'&&c<='9')

    {

        ret=ret*10+(c-'0');

    }

}

inline void OT(int a)

{

    if(a>=10)

    {

        OT(a/10);

    }

    putchar(a%10+'0');

}

char a[1005],b[1005],c[1005];

int dp1[1005][1005],dp2[1005][1005],sum[4005][2],tmp,l1,l2,l3;

void lcs(char *str,int l)//求最长公共子串

{

    int i,j,k;

    FOR(1,l,i)

    {

        if(str[i]==c[1])

        {

            k=1;

            for(j=i;j<=l&&k<=l3;j++)

            {

                if(str[j]==c[k])

                {

                    k++;

                }

            }

            if(k!=l3+1)

            {

                break;

            }

            sum[tmp][0]=i;

            sum[tmp][1]=j-1;

            tmp++;

        }

    }

}

int main()

{

    int t,cas=0,i,j,x,y,ans;

    RD(t);

    while(t--)

    {

        cas++;

        scanf("%s%s%s",a+1,b+1,c+1);

        l1=strlen(a+1);

        l2=strlen(b+1);

        l3=strlen(c+1);

        mem(dp1,0);

        mem(dp2,0);

        FOR(1,l1,i)//dp过程

        {

            FOR(1,l2,j)

            {

                if(a[i]==b[j])

                {

                    dp1[i][j]=dp1[i-1][j-1]+1;

                }

                else

                {

                    dp1[i][j]=max(dp1[i-1][j],dp1[i][j-1]);

                }

            }

        }

        for(i=l1; i>=1; i--)

        {

            for(j=l2; j>=1; j--)

            {

                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]);

                }

            }

        }

        tmp=0;

        lcs(a,l1);

        x=tmp;

        lcs(b,l2);

        y=tmp-x;

        ans=0;

        For(0,x,i)

        {

            For(0,y,j)

            {

                ans=max(ans,dp1[sum[i][0]-1][sum[j+x][0]-1]+dp2[sum[i][1]+1][sum[j+x][1]+1]);

            }

        }

        printf("Case #%d: %d\n",cas,ans+l3);

    }

    return 0;

}


1004 我们队也做出来了,但我暂时还没有研究,据说是个treeDP,但貌似是枚举树的直径。。不懂啦,等待AC

 

 

你可能感兴趣的:(test)