• [置顶] 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
    ");
                }
                else
                {
                    printf("Fanglaoshi
    ");
                }
            }
        }
        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
    ",cas,ans+l3);
        }
        return 0;
    }


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

  • 相关阅读:
    Linux Shell入门
    Linux系统结构
    Ubuntu bond 配置
    VXLAN概述
    lsof
    入驻博客园,希望可以跟大家一起讨论,一起学习和进步。
    版本管理工具小乌龟TortoiseGit的安装和使用(2)
    版本管理工具小乌龟TortoiseGit的安装和使用(1)
    定义变量时未初始化赋值的问题
    BlackBerry 9900刷机
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3263228.html
Copyright © 2020-2023  润新知