hdu 5755(Gauss 消元) &poj 2947
Gambler Bo
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1152 Accepted Submission(s): 471
Special Judge
You have a N×M matrix, every cell has a value in {0,1,2}.
In this game, you can choose a cell in the matrix, plus 2 to this cell, and plus 1 to all the adjacent cells.
for example, you choose the cell (x,y), the value of (x,y) will be plused 2, and the value of (x−1,y)(x+1,y)(x,y−1)(x,y+1) will be plused 1.
if you choose the cell (1,2), the cell (1,2) will be plused 2, and the cell (2,2)(1,1)(1,3) will be plused 1, the cell (0,2) won't be changed because it's out of the matrix.
If the values of some cells is exceed 2, then these values will be modulo 3.
Gambler Bo gives you such a matrix, your task is making all value of this matrix to 0 by doing above operations no more than 2NM times.
In each test, first line is two integers N,M, and following N lines describe the matrix of this test case.
T≤10,1≤N,M≤30, the matrix is random and guarantee that there is at least one operation solution.
Following num lines, each line contains two integers x,y(1≤x≤N,1≤y≤M) describing the operation cell.
The answer may not be unique, you can output any one.
2 3
2 1 2
0 2 0
3 3
1 0 1
0 1 0
1 0 1
1 2
5
1 1
1 3
2 2
3 1
3 3
gauss消元的mod 3 版本,把n*m个格子上的操作全部变成列向量,共n*m个,每个列向量有n*m个元素,做一遍gauss消元就能解出。
另:优化后因为第i行的状态可以由i+1行确定,所以能建立m个方程,每个方程 M 个变量进行高斯消元,解出解后代回去得到每个元素应该被操作的次数。详见
【传送门】
我的裸gauss消元代码如下:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define clr(x) memset(x,0,sizeof(x))
#define clrdown(x) memset(x,-1,sizeof(x))
#define maxn 910
using namespace std;
int A[maxn][maxn];
int free_x[maxn];
int x[maxn];
int mov[][]={,,,-,,,-,};
void init(int n,int m);
void gauss(int n,int m);
void print(int n,int m);
int exgcd(int a,int b,int &x,int &y);
int lcm(int a,int b);
int gcd(int a,int b);
int main()
{
int T,p,num,n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
init(n,m);
gauss(n*m,n*m);
print(n,m);
}
return ;
}
void print(int n,int m)
{
int sum=;
for(int i=;i<n*m;i++)
sum+=x[i];
printf("%d\n",sum);
for(int i=;i<n;i++)
for(int j=;j<m;j++)
while(x[i*m+j]>)
{
printf("%d %d\n",i+,j+);
x[i*m+j]--;
}
return ;
}
void init(int n,int m)
{
int t;
clr(A);
for(int i=;i<n;i++)
for(int j=;j<m;j++)
{
t=i*m+j;
A[t][t]=;
for(int k=;k<;k++)
if(i+mov[k][]>= && i+mov[k][]<n && j+mov[k][]>= && j+mov[k][]<m)
A[(i+mov[k][])*m+j+mov[k][]][t]=;
}
t=n*m;
for(int i=;i<n;i++)
for(int j=;j<m;j++)
{
scanf("%d",&A[i*m+j][t]);
A[i*m+j][t]=(-A[i*m+j][t])%;
}
clrdown(x);
clr(free_x);
}
void gauss(int n,int m)
{
// for(int i=0;i<n;i++)
// {
// for(int j=0;j<=m;j++)
// printf("%d ",A[i][j]);
// printf("\n");
// }
int k,col,num=,max_r,dou,max_x,LCM,ta,tb;
for(k=,col=;k<n && col<m;k++,col++)
{
max_r=k;
max_x=abs(A[k][col]);
for(int i=k+;i<n;i++)
if(max_x<abs(A[i][col]))
{
max_x=abs(A[i][col]);
max_r=i;
}
if(max_r!=k)
{
for(int j=col;j<=m;j++)
swap(A[k][j],A[max_r][j]);
}
if(A[k][col]==)
{
k--;
free_x[num++]=col;
continue;
}
for(int i=k+;i<n;i++)
if(A[i][col])
{
LCM=lcm(A[k][col],A[i][col]);
ta=LCM/A[i][col];
tb=LCM/A[k][col];
for(int j=col;j<=m;j++)
{
A[i][j]=((A[i][j]*ta-A[k][j]*tb)%+)%;
}
}
}
int temp;
for(int i=;i<num;i++)
x[free_x[i]]=;
int xi,yi;
for(int i=k-,c=m-;i>=;c=m-,i--)
{
temp=A[i][m];
while(x[c]!=-)
{
if(A[i][c])
temp=((temp-(x[c]*A[i][c])%)%+)%;
c--;
}
exgcd(A[i][c],,xi,yi);
xi=(xi%+)%;
x[c]=(temp*xi%+)%;
}
// for(int i=0;i<n;i++)
// {
// for(int j=0;j<=m;j++)
// printf("%d ",A[i][j]);
// printf("\n");
// }
// for(int i=0;i<m;i++)
// printf("%d ",x[i]);
return ;
}
int exgcd(int a,int b,int &x,int &y)
{
if(b==)
{
x=;
y=;
return a;
}
else
{
int r=exgcd(b,a%b,y,x);
y-=x*(a/b);
return r;
}
}
int gcd(int a,int b)
{
int c;
while(b!=)
{
c=a%b;
a=b;
b=c;
}
return a;
}
int lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
同样的,poj2947: 【传送门】
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define clr(x) memset(x,0,sizeof(x))
#define clrdown(x) memset(x,-1,sizeof(x))
#define maxn 310
#define maxm 310
#define mod 7
using namespace std;
int A[maxn][maxm];//Gauss消元的增广矩阵
int x[maxm];//整数解集
char week[][] = {"MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
char s1[],s2[];
void init(int n,int m);//矩阵初始化操作
int gauss(int n,int m);//gauss消元部分
int exgcd(int a,int b,int &x,int &y);//扩展欧几里得求逆元,对于模mod的矩阵除法需要
int lcm(int a,int b);
int gcd(int a,int b);
int findnum(char *s);
int main()
{
int n,m,p;
while(scanf("%d%d",&n,&m) && n && m)
{
init(n,m);
p=gauss(m,n);
if(p==-)
printf("Inconsistent data.\n");
if(p==-)
printf("Multiple solutions.\n");
if(p==)
{
for(int i=;i<n;i++)
printf("%d%c", x[i], i == n- ?'\n':' ');
}
}
return ;
}
//读入增广矩阵
void init(int n,int m)
{
clr(A);
int p,ct;
for(int i=;i<m;i++)
{
scanf("%d%s%s",&p,&s1,&s2);
A[i][n]=((findnum(s2)-findnum(s1)+)+mod)%mod;
for(int j=;j<p;j++)
{
scanf("%d",&ct);
A[i][ct-]++;
A[i][ct-]=A[i][ct-]%mod;
}
}
clrdown(x);
return ;
}
int gauss(int n,int m)
{
int k,col,max_r,dou,max_x,LCM,ta,tb;
//k为当前操作行,col为操作主元素所在列
for(k=,col=;k<n && col<m;k++,col++)
{
//若A[K][col]不为col列最大,则将k行与k+1到n-1行中A[i][col]绝对值最大的行交换
max_r=k;
max_x=A[k][col];
for(int i=k+;i<n;i++)
if(max_x<A[i][col])
{
max_x=A[i][col];
max_r=i;
}
if(max_r!=k)
{
for(int j=col;j<=m;j++)
swap(A[k][j],A[max_r][j]);
}
//若k到n-1行A[i][col]全为0,则主元素指向当前行下一列的元素
if(A[k][col]==)
{
k--;
//自由变元为当前col
continue;
}
for(int i=k+;i<n;i++)
if(A[i][col])
{
LCM=lcm(A[k][col],A[i][col]);
ta=LCM/A[i][col];
tb=LCM/A[k][col];
for(int j=col;j<=m;j++)
{
A[i][j]=((A[i][j]*ta-A[k][j]*tb)%mod+mod)%mod;
}
}
}
for(int i=k;i<n;i++)
if(A[i][m]!=)
return -;
if(m-k>) return -;
int xi,yi,temp;
for(int i=k-,c=m-;i>=;c=m-,i--)
{
temp=A[i][m];
while(x[c]!=-)
{
if(A[i][c])
temp=((temp-x[c]*A[i][c])%mod+mod)%mod;
c--;
}
temp=(temp%mod+mod)%mod;
exgcd(A[i][c],mod,xi,yi);
xi=(xi%mod+mod)%mod;
x[c]=((temp*xi)%mod+mod)%mod;
if(x[c]<) x[c]+=mod;
}
return ;
}
int exgcd(int a,int b,int &x,int &y)
{
if(b==)
{
x=;
y=;
return a;
}
else
{
int r=exgcd(b,a%b,y,x);
y-=x*(a/b);
return r;
}
}
int gcd(int a,int b)
{
int c;
while(b!=)
{
c=a%b;
a=b;
b=c;
}
return a;
}
int lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
int findnum(char *s)
{
for(int i=;i<mod;i++)
{
if(strcmp(s,week[i])==)
return i;
}
}
Gauss消元
hdu 5755(Gauss 消元) &poj 2947的更多相关文章
- poj 1681(Gauss 消元)
Painter's Problem Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 5875 Accepted: 2825 ...
- POJ 1830 开关问题(Gauss 消元)
开关问题 Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 7726 Accepted: 3032 Description ...
- HDU 2827 高斯消元
模板的高斯消元.... /** @Date : 2017-09-26 18:05:03 * @FileName: HDU 2827 高斯消元.cpp * @Platform: Windows * @A ...
- $Gauss$消元
$Gauss$消元 今天金牌爷来问我一个高消的题目,我才想起来忘了学高消... 高斯消元用于解线性方程组,也就是形如: $\left\{\begin{matrix}a_{11}x_1+a_{12}x_ ...
- 求一个n元一次方程的解,Gauss消元
求一个n元一次方程的解,Gauss消元 const Matrix=require('./Matrix.js') /*Gauss 消元 传入一个矩阵,传出结果 */ function Gauss(mat ...
- Gauss 消元(模板)
/* title:Gauss消元整数解/小数解整数矩阵模板 author:lhk time: 2016.9.11 没学vim的菜鸡自己手打了 */ #include<cstdio> #in ...
- hdu 3915 高斯消元
http://acm.hdu.edu.cn/showproblem.php?pid=3915 这道题目是和博弈论挂钩的高斯消元.本题涉及的博弈是nim博弈,结论是:当先手处于奇异局势时(几堆石子数相互 ...
- [置顶] hdu 4418 高斯消元解方程求期望
题意: 一个人在一条线段来回走(遇到线段端点就转变方向),现在他从起点出发,并有一个初始方向, 每次都可以走1, 2, 3 ..... m步,都有对应着一个概率.问你他走到终点的概率 思路: 方向问 ...
- POJ1830开关问题——gauss消元
题目链接 分析: 第一个高斯消元题目,操作是异或.奇偶能够用0.1来表示,也就表示成bool类型的方程,操作是异或.和加法没有差别 题目中有两个未知量:每一个开关被按下的次数(0.1).每一个开关的转 ...
随机推荐
- 快速搭建 DNS 服务器: skydns + etcd
参考: [ skynetservice github ] [ skydns 测试记录 CSDN ] etcd 安装配置 安装 yum install etcd 配置 sed -i 's@ETCD_LI ...
- JAVA Frame 响应窗口关闭事件
/* * To change this license header, choose License Headers in Project Properties. * To change this t ...
- 代码合并:Merge、Rebase 的选择
图解 Git 命令 基本用法 上面的四条命令在工作目录.stage 缓存(也叫做索引)和 commit 历史之间复制文件. git add files 把工作目录中的文件加入 stage 缓存 git ...
- Python【模块】importlib,requests
内容概要: 模仿django中间件的加载方式 importlib模块 requests模块 rsplit() 用实际使用的理解来解释两个模块 importlib模块 ...
- KVM初始化过程
转载:http://blog.csdn.net/dashulu/article/details/17074675 之前打算整理一下在Guest VM, KVM, QEMU中IO处理的整个流程,通过查阅 ...
- MACHINE_START与MACHINE_END【转】
转自:http://blog.csdn.net/cxw3506/article/details/8475965 版权声明:本文为博主原创文章,未经博主允许不得转载. 在移植Linux时,有个结构体需要 ...
- FAN54015 充電電流 軟硬體設定
Ex1: Vrsense 選 37.4 mV --- 在第二張圖 Rsense 選 50 mΩ --- 在第三張圖 37.4 / 50 = 748 mA Ex2: Vrsense 選 44.2 mV ...
- 【UOJ#169】元旦老人与数列
论文题. 考虑到这题的维护和区间操作是反向的,也就是说无法像V那题快速的合并标记. 我们知道,一个区间的最小值和其他值是可以分开来维护的,因为如果一个区间被整体覆盖,那么最小值始终是最小值. 对于被覆 ...
- [Think] position与anchorPoint关系
1.简介: 最近在学习动画,所以接触到了CAlayer类. 其中的position与anchorPoint关系一感觉一头雾水,网上有篇文章 彻底理解position和anchorPoint关系 里面 ...
- C++中string类的方法
C++ string类的方法 具体每个方法怎么使用,可以参考相应的链接. 总的链接为http://www.cplusplus.com/reference/string/string/(C++参考文档) ...