2018.12.8 jzoj C组题解

版权声明:本博客的博文版权为2018韦泽鑫所有,复制文章转载时记得附上本博客的地址哦 https://blog.csdn.net/qq_40167327/article/details/85171095

T1

这道题bfs(按[连通器原理](https://baike.baidu.com/item/%E8%BF%9E%E9%80%9A%E5%99%A8/1534580)),注意当h=n+1时要搜上面的边

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[1111][1111],q1[1000002],q2[1000002];
int walk1[5] = {0,1,0,-1,0};
int walk2[5] = {0,0,1,0,-1};
int n,m,h;
void bfs(int x,int y)
{
    int head = 1;
    int tail = 2;
    q1[1] = x;
    q2[1] = y;
    a[x][y] = 2;
    while (head < tail)
    {
        for (int i=1;i<=4;i++)
        {
            int tx = q1[head] + walk1[i];
            int ty = q2[head] + walk2[i];
            if(tx >= 1 && ty >= 1 && tx<=n && ty<=m && !a[tx][ty] && tx>=n-h+1)
            {
                q1[tail] = tx;
                q2[tail++] = ty;
                a[tx][ty] = 2;
            }
        }
        head++;
    }
}
int main()
{
    freopen("cruise.in","r",stdin);
    freopen("cruise.out","w",stdout);
    cin>>n>>m>>h;
    if(h > n) h = n;
    memset(a,0,sizeof(a));
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
        {
            char s;
            cin>>s;
            if(s == '1') a[i][j] = 1;
        }
    int x = 0;
    int y = 0;
    for (int i=n;i>=n-h+1;i--)
        for (int j=1;j<=m;j++)
            if(!a[i][j])
            {
                if(i > 1 && j > 1 && i < n && j < m) continue;
                x = i;
                y = j;
                bfs(x,y);
            }
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=m;j++)
            cout<<a[i][j];
        cout<<endl;
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

T2

这道题O(n*t),只需要遇到折点就记录就行,注意前后两个数相等的情况

#include<cstdio>
using namespace std;
int a[250002];
int main()
{
    freopen("rose.in","r",stdin);
    freopen("rose.out","w",stdout);
    int t,n;
    scanf("%d%d",&t,&n);
    for (int i=1;i<=t;i++)
    {
        bool p = true;
        for (int j=1;j<=n;j++)
            scanf("%d",&a[j]);
        int l=1;
        int w=1,x=0,y=0,z=0;
        for (int j=2;j<=n;j++)
            if(l % 2 == 0 && a[j]>a[j-1])
            {
                l++;
                if(l == 3) y = j-1;
            }
            else if(l % 2 == 1 && a[j]<a[j-1])
            {
                l++;
                if(l == 2) x = j-1;
                if(l == 4) z = j-1;
            }
            else if(a[j] == a[j-1])
            {
                p = false;
                break;
            }
        if(p)
        {
            if(l == 4 && w != x && x != y && y !=z) printf("TAK\n");
            else printf("NIE\n");
        }
        else printf("NIE\n");
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}

T3

这道题Floyd,暴力算出不删点和删2~n-1的点的各个最短路,判断即可

#include<cmath>
#include<cstdio>
long long int n,m,p[101];
long double map[101][101],chu[101][101],cha[101][101];
int main()
{
    freopen("fool.in","r",stdin);
    freopen("fool.out","w",stdout);
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            chu[i][j]=-217483647.00;cha[i][j]=chu[i][j];map[i][j]=chu[i][j];
        }
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%LF",&map[i][i]);map[i][i]=1-map[i][i]*0.01;chu[i][i]=map[i][i];cha[i][i]=map[i][i];
    }
    for(int i=1;i<=m;i++)
    {
        long long int x,y;
        scanf("%lld%lld",&x,&y);
        map[x][y]=map[y][y];chu[x][y]=map[x][y];cha[x][y]=map[x][y];
        map[y][x]=map[x][x];chu[y][x]=map[y][x];cha[y][x]=map[y][x];
    }
    p[1]=1;p[n]=1;
    for(int k=1;k<=n;k++)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(i!=j&&i!=k&&j!=k&&chu[i][k]*chu[k][j]>chu[i][j]&&chu[i][k]>=0&&chu[k][j]>=0)
                {
                    chu[i][j]=chu[i][k]*chu[k][j];
                }
            }
        }
    }
    long long int xc=chu[1][n]*1000000;
    for(int a=2;a<n;a++)
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                map[i][j]=cha[i][j];
            }
        }
        for(int i=1;i<=n;i++)map[a][i]=-10;
        for(int i=1;i<=n;i++)map[i][a]=-10;
        for(int k=1;k<=n;k++)
        {
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {
                    if(i!=j&&i!=k&&j!=k&&map[i][k]*map[k][j]>map[i][j]&&map[i][k]>=0&&map[k][j]>=0)
                    {
                        map[i][j]=map[i][k]*map[k][j];
                    }
                }
            }
        }
        long long int cx=map[1][n]*1000000;
        if(xc>cx)
        {
            p[a]=1;
        }
    }
    for(int i=1;i<=n;i++)printf("%lld\n",p[i]);
    return 0;
}

T4

这道题动态转移方程,f[i][j]=max(f[i][j-1],f[i-1][j])+a[i][j]即可

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#define mod 1000000007
using namespace std;
long long int f[2001][2001],n,m,a[2001][2001],zyf[2001][2001];
int main()
{
    freopen("chess.in","r",stdin);
    freopen("chess.out","w",stdout);
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            scanf("%lld",&a[i][j]);f[i][j]=-2147483647;
        }
    }
    zyf[1][1]=1;
    f[1][1]=a[1][1];
    for(int i=2;i<=m;i++)
    {
        f[1][i]=a[1][i]+f[1][i-1];zyf[1][i]=1;
    }
    for(int i=2;i<=n;i++)
    {
        f[i][1]=a[i][1]+f[i-1][1];zyf[i][1]=1;
    }
    for(int i=2;i<=n;i++)
    {
        for(int j=2;j<=m;j++)
        {
            f[i][j]=max(f[i][j-1],f[i-1][j])+a[i][j];
            if(f[i][j-1]>f[i-1][j])
            {
                zyf[i][j]=zyf[i][j-1]%mod;
            }
            if(f[i][j-1]<f[i-1][j])
            {
                zyf[i][j]=zyf[i-1][j]%mod;
            }
            if(f[i][j-1]==f[i-1][j])
            {
                zyf[i][j]=(zyf[i-1][j]+zyf[i][j-1])%mod;
            }
        }
    }
    printf("%lld\n%lld",f[n][m],zyf[n][m]);
    return 0;
}

转载请注明出处啊,亲~

猜你喜欢

转载自blog.csdn.net/qq_40167327/article/details/85171095
今日推荐