hdu5755Gambler Bo
2016-07-27 10:11
288 查看
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5755
题意:给定一个只含{0,1,2}的n*m的矩阵。有一种操作:将(x,y)位置+2同时(x-1,y),(x+1,y),(x,y-1),(x,y+1)都会+1。要求进行<=2*n*m次操作将矩阵变为全0,数据保证至少有一组解。
分析:前段时间刚做完一道这样的题,比赛的时候因为卡其他题了这道题却没看到。想多练一下的转E.Harmonious Matrices。。再说下这种题的思路吧,我们可以设第一行每个位置的操作次数为xi,0<=xi<3,然后显然知道了第一行我们就能将整个矩阵都推导出来。如果直接暴力枚举显然是不行的,我们观察发现每填完一行只能确定上一行的元素,那么想要确定n行显然是要推到第n+1行,但是实际情况第n+1行全为0。所以对于第n+1行的m个位置我们能得到m个含m个未知数xi等于0的方程,那么只要解这个方程组就能得到答案x啦。PS:出题人的做法类似但是复杂度上差很多,出题人说的做法是设n*m个变量,然后根据题目的要求建n*m个方程,这样是O(n^3*m^3)的。我的做法是设m个变量,这样就能O(m^3)啦。
代码:
#include<map> #include<set> #include<cmath> #include<queue> #include<bitset> #include<math.h> #include<vector> #include<string> #include<stdio.h> #include<cstring> #include<iostream> #include<algorithm> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const int N=35; const int mod=100000000; const int MOD1=1000000007; const int MOD2=1000000009; const double EPS=0.00000001; typedef long long ll; const ll MOD=1000000007; const int MAX=2000000010; const ll INF=1ll<<55; const double pi=acos(-1.0); typedef double db; typedef unsigned long long ull; int a ,p ,f ; int get(int i,int j,int k) { int sum=(f[i][j-1][k]+2*f[i][j][k]+f[i][j+1][k]+f[i-1][j][k])%3; return ((3-sum)%3+3)%3; } int getans(int i,int j) { int sum=(p[i][j-1]+2*p[i][j]+p[i][j+1]+p[i-1][j]+a[i][j])%3; return ((3-sum)%3+3)%3; } void gauss(int n,int m) { int d,i,j,k,h,w=0; for (i=1,j=1;j<m;j++,w=0) { for (k=i;k<=n;k++) if (p[k][j]) w=k; if (w) { for (k=j;k<=m;k++) swap(p[i][k],p[w][k]); for (k=i+1;k<=n;k++) if (p[k][j]) { d=(p[k][j]*p[i][j]%3+3)%3; for (h=j;h<=m;h++) p[k][h]=((p[k][h]-d*p[i][h])%3+3)%3; } i++; } if (i>n) break ; } for (j=1;j<=m;j++) f[1][j][j]=0; for (j=i-1;j;j--) { for (k=1;k<m;k++) if (p[j][k]) break ; for (d=0,h=k+1;h<m;h++) if (f[1][h][h]&&p[j][h]) d=(d+f[1][h][h]*p[j][h])%3; f[1][k][k]=p[j][k]*(3-d+p[j][m])%3; } memset(p,0,sizeof(p)); for (j=1;j<=m;j++) p[1][j]=(f[1][j][j]+3)%3; } int main() { int i,j,k,n,m,t,ans; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); memset(a,0,sizeof(a)); for (i=1;i<=n;i++) for (j=1;j<=m;j++) scanf("%d", &a[i][j]); memset(f,0,sizeof(f)); for (i=1;i<=m;i++) f[1][i][i]=1; for (i=2;i<=n+1;i++) for (j=1;j<=m;j++) { f[i][j][m+1]=(3-a[i-1][j]+get(i-1,j,m+1))%3; for (k=1;k<=m;k++) f[i][j][k]=get(i-1,j,k); } memset(p,0,sizeof(p)); for (i=1;i<=m;i++) { p[i][m+1]=((3-f[n+1][i][m+1])%3+3)%3; for (j=1;j<=m;j++) p[i][j]=f[n+1][i][j]; } gauss(m,m+1);ans=0; for (i=1;i<=m;i++) ans+=p[1][i]; for (i=2;i<=n;i++) for (j=1;j<=m;j++) p[i][j]=getans(i-1,j),ans+=p[i][j]; printf("%d\n", ans); for (i=1;i<=n;i++) for (j=1;j<=m;j++) for (k=1;k<=p[i][j];k++) printf("%d %d\n", i, j); } return 0; }
相关文章推荐
- QT 常见格式转换
- linux配置java环境变量
- 创建kafkatopic和productor
- SpringMVC + ajax
- cal 2016 linux 中显示日历
- MySQL数据库InnoDB和MyISAM数据引擎的差别
- 关于iOS夺宝类App20.4的支付问题
- af:panelTabbed 无法扩展到整个页面。
- Linux_Yum源_为Centos添加第三方源
- Android studio 下 Terminal 命令
- 第二篇.AIDL之app应用层
- HashMap、ArraryList、LinkList、HasSet底层实现结构
- UVa 10285
- QC解决登陆时提示 setup_a.cab this file didn't pass signature checking或者初始化失败问题
- Coursera算法第一周
- 用bash命令得到Windows一个目录下的所有文件并且把结果输入到一个文件
- 【前台页面 BUG】回车按钮后,页面自动跳转
- Tuxedo介绍与安装
- 自定义View的构造方法
- LightOJ 1062 Crossed Ladders(大楼距离,二分)