• BJOI2015 Day2


    轮到罗剑桥出题了

    这是什么风格,中文名称与英文名称分明对不上吗233

    T1:

    似乎只会做这道题23333

    A....BE

    ........

    C....DF

    据题意数学变形得A-C<=B-D,B-D<=E-F,即左右的差是递增的。

    A....B

    .......

    C....D

    E....F

    据题意数学变形得A-B<=C-D,C-D<=E-F,即上下的差是递增的。

    那么令f1[i][j]=A[i][j]-A[i+1][j],f2[i][j]=A[i][j]-A[i][j+1]。

    只有当f1[i][j-1]<=f1[i][j]且f2[i-1][j]<=f2[i][j]时 (i,j)才能进入矩形中。

    那么问题就转化成最大子矩形,其内部没有坏点。

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=1010;
    int A[maxn][maxn],B[maxn][maxn],C[maxn][maxn],n,m,ans;
    int is[maxn][maxn];
    int right[maxn],left[maxn],up[maxn][maxn];
    int main() {
        freopen("neo.in","r",stdin);
        freopen("neo.out","w",stdout);
        n=read();m=read();
        rep(i,1,n) rep(j,1,m) A[i][j]=read();
        rep(i,1,n) rep(j,1,m) B[i][j]=A[i][j]-A[i+1][j],C[i][j]=A[i][j]-A[i][j+1];
        n--;m--;
        rep(i,1,n) rep(j,1,m) if(B[i][j]<=B[i][j+1]&&C[i][j]<=C[i+1][j]) is[i][j]=1;
        rep(i,1,n) {
            rep(j,1,m) {
                if(!is[i][j]) continue;
                up[i][j]=up[i-1][j]+1;
                if(j==1) left[j]=1;
                else {
                    left[j]=j;
                    while(up[i][left[j]-1]>=up[i][j]) left[j]=left[left[j]-1];
                }
            }
            for(int j=m;j;j--) {
                if(!is[i][j]) continue;
                if(j==m) right[j]=m;
                else {
                    right[j]=j;
                    while(up[i][right[j]+1]>=up[i][j]) right[j]=right[right[j]+1];
                }
                ans=max(ans,(up[i][j]+1)*(right[j]-left[j]+2));
            }
        }
        printf("%d
    ",ans);
        return 0;    
    }
    View Code

     T2:简要题意,计算从最上角上方连一条管道到最下角下方的方案书数。

    显然是不可做的插头DP,写个暴搜60

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=15;
    int n,m,ans;
    char A[maxn][maxn];
    int have[maxn][maxn];
    int mx[]={1,-1,0,0},my[]={0,0,1,-1};
    void dfs(int x,int y) {
         have[x][y]=1;
         if(x==n&&y==m) ans++;
         else rep(dir,0,3) if(x>=1&&x<=n&&y>=1&&y<=m&&!have[x+mx[dir]][y+my[dir]]&&A[x+mx[dir]][y+my[dir]]=='.') dfs(x+mx[dir],y+my[dir]);
         have[x][y]=0;
    }
    int main() {
        freopen("voda.in","r",stdin);
        freopen("voda.out","w",stdout);
        n=read();m=read();
        rep(i,1,n) scanf("%s",A[i]+1);
        if(A[1][1]=='#'||A[n][m]=='#') {puts("0");return 0;}
        dfs(1,1);printf("%d
    ",ans%10007);
        return 0;    
    }
    View Code

    T3:有一个N层M格的书架,可以将一本书移动到另一层,也可以把同一层的书左右移动,求从初始状态到最终状态的最少移动数。

    考虑那些前后所在层不变的书,应对答案贡献总数-LCS的数目,如果这层全满,需要答案额外+1(先将一本拿到别层再拿回来)。

    对于前后所在层变化的书,答案要+1表示移动一次,如果所在连通分量全满,同理答案要再+1.

    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<algorithm>
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    using namespace std;
    inline int read() {
        int x=0,f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const int maxn=1010;
    int m,C[maxn],t[maxn*maxn],g[maxn];
    int get(int* C,int len) {
        int ans=0;
        rep(i,1,len) g[i]=1<<30;
        rep(i,1,len) {
            int k=lower_bound(g+1,g+len+1,C[i])-g;
            ans=max(ans,k);g[k]=C[i];
        }
        return ans;
    }
    int n,A[maxn][maxn],B[maxn][maxn],yes[maxn],ans;
    int pos[maxn*maxn],pos2[maxn*maxn],first[maxn],next[maxn*maxn*2],to[maxn*maxn*2],e;
    void AddEdge(int u,int v) {
        ans++;
        to[++e]=v;next[e]=first[u];first[u]=e;
        to[++e]=u;next[e]=first[v];first[v]=e;
    }
    int vis[maxn],f[maxn];
    int dfs(int x) {
        if(vis[x]) return f[x];vis[x]=1;
        int& ans=f[x];ans=!yes[x];
        for(int i=first[x];i;i=next[i]) ans&=dfs(to[i]);
        return ans;
    }
    int main() {
        freopen("police20.in","r",stdin);
        freopen("police.out","w",stdout);
        n=read();m=read();int ok=0,dif=0;
        rep(i,1,n) rep(j,1,m) {
            A[i][j]=read();
            if(!A[i][j]) ok=yes[i]=1;
            else pos[A[i][j]]=i,pos2[A[i][j]]=j;
        }
        rep(i,1,n) rep(j,1,m) {
            B[i][j]=read();
            if(B[i][j]&&i!=pos[B[i][j]]) AddEdge(i,pos[B[i][j]]);
        }
        rep(i,1,n) {
            int len=0;
            rep(j,1,m) if(B[i][j]&&pos[B[i][j]]==i) C[++len]=pos2[B[i][j]];
            int tmp=len-get(C,len);
            if(tmp) ans+=tmp+(len==m);
        }
        if(ans&&!ok) puts("-1"); 
        else {
            rep(i,1,n) if(!vis[i]&&first[i]) ans+=dfs(i);
            printf("%d
    ",ans);
        }
        return 0;    
    }
    View Code
  • 相关阅读:
    用sqlite3创建数据库实现数据固化功能
    MSP430F169单片机中的LED动态显示
    在GTK中设计简单的菜单栏
    在GTK下设置窗口背景图片
    在GTK+2.0中实现简单的多用户登入系统
    ubuntu 执行sudo apt-get install libgtk2.0-devs安装gtk+-2.0时报错Failed to fetch IP:https://的解决
    Linux下Makefile,静态库,动态库的实现
    Spring 之 BeanFactory 源码
    pig trial-group,foreach
    scala
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/4638281.html
Copyright © 2020-2023  润新知