zoukankan      html  css  js  c++  java
  • bzoj2003 [Hnoi2010]矩阵

    Description

    Input

    第一行包含三个正整数N M P表示矩阵的行数列数以及每个数的范围,接下来N行每行包含M个非负整数,其中第i行第j个数表示以格子(i,j)为右下角的2*2子矩阵中的数的和。保证第一行与第一列的数均为0,且每个和都不超过4(P-1)。

    Output

    包含N行,每行M个整数,描述你求出的矩阵,相邻的整数用空格分开。(行末不要有多余空格)

    Sample Input

    3 3 3
    0 0 0
    0 4 5
    0 5 3

    Sample Output

    0 0 2
    2 2 1
    1 0 0

    HINT 

    1<=N,M<=200

    1<P<=10

    正解:搜索。

    好像还是寒假的时候就考过这题,然而当时在爆刚另外一题以至于这题连暴力都没写。。

    然而现在还是不会做,感觉这题真的好难啊。。

    于是我自己肯定是讲不清楚的,所以给一个题解吧:HNOI2010题解 (里面有一个指数写错了)

    还是简单提一下,大概就是先构造一个矩阵$c$,它是满足和性质的一个答案,但每个数的取值范围不一定合法。

    然后我们又可以发现答案矩阵之和矩阵的第一行和第一列有关,进一步可以发现$a[i][j]$只与$c[i][j],a[1][1],a[1][j],a[i][1]$有关。

    然后可以得到$a[i][j]=c[i][j]+(-1)^{i+j-1}a[1][1]+(-1)^{i-1}a[1][j]+(-1)^{j-1}a[i][1]$。

    然后我们搜索第一行,每搜出一个数就根据这一列的所有数确定第一列的取值范围,如果不合法就退出搜索。

    然后状态数就神奇地减少了,并且跑得飞快。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define N (510)
     6 
     7 using namespace std;
     8 
     9 const int f[2]={1,-1};
    10 
    11 int a[N][N],c[N][N],dn[N][N],up[N][N],n,m,p;
    12 
    13 il int gi(){
    14   RG int x=0,q=1; RG char ch=getchar();
    15   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    16   if (ch=='-') q=-1,ch=getchar();
    17   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    18   return q*x;
    19 }
    20 
    21 il int dfs(RG int j){
    22   if (j>m) return 1;
    23   for (a[1][j]=0;a[1][j]<p;++a[1][j]){
    24     RG int fg=1,Min,Max;
    25     for (RG int i=2;i<=n;++i){
    26       Min=(c[i][j]+f[(i+j-1)&1]*a[1][1]+f[(i-1)&1]*a[1][j])*f[j&1];
    27       Max=(c[i][j]+f[(i+j-1)&1]*a[1][1]+f[(i-1)&1]*a[1][j]-p+1)*f[j&1];
    28       if (Min>Max) swap(Min,Max);
    29       dn[i][j]=max(dn[i][j-1],Min),up[i][j]=min(up[i][j-1],Max);
    30       if (dn[i][j]>up[i][j]){ fg=0; break; }
    31     }
    32     if (fg && dfs(j+1)) return 1;
    33   }
    34   return 0;
    35 }
    36 
    37 int main(){
    38 #ifndef ONLINE_JUDGE
    39   freopen("matrix.in","r",stdin);
    40   freopen("matrix.out","w",stdout);
    41 #endif
    42   n=gi(),m=gi(),p=gi();
    43   for (RG int i=1;i<=n;++i)
    44     for (RG int j=1,x;j<=m;++j)
    45       x=gi(),c[i][j]=x-c[i-1][j]-c[i][j-1]-c[i-1][j-1],up[i][j]=p-1;
    46   for (a[1][1]=0;a[1][1]<p && !dfs(2);++a[1][1]);
    47   for (RG int i=2;i<=n;++i) a[i][1]=dn[i][m];
    48   for (RG int i=1;i<=n;++i)
    49     for (RG int j=1;j<=m;++j)
    50       printf("%d%s",c[i][j]+f[(i+j-1)&1]*a[1][1]+f[(i-1)&1]*a[1][j]+f[(j-1)&1]*a[i][1],j<m ? " " : "
    ");
    51   return 0;
    52 }
  • 相关阅读:
    easyui struts后台实现tree返回json数据
    jquery扩展方法
    EasyUI tree扩展获取实心节点
    Hibernate之AbstractEntityPersister
    No CurrentSessionContext configured 异常解决
    Dubbo远程调用服务框架原理与示例
    mongodb高级操作及在Java企业级开发中的应用
    Java和MongoDB之Hello World
    Vmware 虚拟的Linux系统如何与宿主主机共享上网
    VM VirtualBox 上安装 CentOs6.4(详细)
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7527725.html
Copyright © 2011-2022 走看看