POJ 3735 Training little cats (矩阵快速幂+矩阵构造好题)
2018-02-05 21:01
381 查看
题目:POJ 3735 Training little cats
PS:做完了大路边上的题目,剩下的都是些难想难敲的题目了。所以看书是一方面,做题又是另一方面。这个题目给了我两个收获,
一个是代码上的优化,另一个是矩阵的非递推关系形式的构造。关于代码优化,这个题目靠普通的高代定义写法是过不去的,需要优
化,而这种写法不是从数学的角度,而是从程序优化的角度给了一种符合定义的新的写法。关键代码如下:
for (i=1;i<=n;i++){
for (k=1;k<=n;k++){
if (a[i][k])for (j=1;j<=n;j++){
ans.a[i][j]+=a[i][k]*fun.a[k][j];
}
}
}
这里把j,k调换就是定义的写法,优化了零较多的情况。
题目大意:n只猫做k个动作,循环m次,动作包括拿花生,吃花生和换花生。
解题思路:这个题目由于m很大,所以没有办法直接进行模拟,于是联想到矩阵快速幂,用连乘的方式表示状态。拿走花生,则+1,
交换等于换行,吃掉就把这一行清空(因为对之后就没有任何影响了)
ac代码:
#include<iostream>
#include<cstring>
#include<cmath>
#include<iomanip>
#include<algorithm>
#include<cstdio>
using namespace std;
struct matrix{
long long a[110][110],n;
matrix(long long f,long long size){
long long i;
n=size;
memset (a,0,sizeof(a));
if (f==0)return ;
for (i=1;i<=n;i++)a[i][i]=1;
}
matrix operator*(const matrix&fun)const{
matrix ans(0,n);
long long i,j,k;
for (i=1;i<=n;i++){
for (k=1;k<=n;k++){
if (a[i][k])for (j=1;j<=n;j++){
ans.a[i][j]+=a[i][k]*fun.a[k][j];
}
}
}
return ans;
}
matrix qpow(long long x)const{
matrix ans(1,n);
matrix tmp=(*this);
while (x){
if (x&1)ans=ans*tmp;
tmp=tmp*tmp;
x>>=1;
}
return ans;
}
};
int main(){
long long i,j,n,m,k,x,y;
char fun;
while (scanf("%lld%lld%lld",&n,&m,&k)!=EOF&&n+m+k){
matrix ans(1,n+1);
for (i=1;i<=k;i++){
scanf("%s%lld",&fun,&x);
if (fun=='g')ans.a[x][n+1]++;
else if (fun=='e'){
for (j=1;j<=n+1;j++){
ans.a[x][j]=0;
}
}
else {
scanf("%lld",&y);
for (j=1;j<=n+1;j++)swap(ans.a[x][j],ans.a[y][j]);
}
}
ans=ans.qpow(m);
for (i=1;i<=n;i++){
printf("%lld%c",ans.a[i][n+1],i==n?'\n':' ');
}
}
}
PS:做完了大路边上的题目,剩下的都是些难想难敲的题目了。所以看书是一方面,做题又是另一方面。这个题目给了我两个收获,
一个是代码上的优化,另一个是矩阵的非递推关系形式的构造。关于代码优化,这个题目靠普通的高代定义写法是过不去的,需要优
化,而这种写法不是从数学的角度,而是从程序优化的角度给了一种符合定义的新的写法。关键代码如下:
for (i=1;i<=n;i++){
for (k=1;k<=n;k++){
if (a[i][k])for (j=1;j<=n;j++){
ans.a[i][j]+=a[i][k]*fun.a[k][j];
}
}
}
这里把j,k调换就是定义的写法,优化了零较多的情况。
题目大意:n只猫做k个动作,循环m次,动作包括拿花生,吃花生和换花生。
解题思路:这个题目由于m很大,所以没有办法直接进行模拟,于是联想到矩阵快速幂,用连乘的方式表示状态。拿走花生,则+1,
交换等于换行,吃掉就把这一行清空(因为对之后就没有任何影响了)
ac代码:
#include<iostream>
#include<cstring>
#include<cmath>
#include<iomanip>
#include<algorithm>
#include<cstdio>
using namespace std;
struct matrix{
long long a[110][110],n;
matrix(long long f,long long size){
long long i;
n=size;
memset (a,0,sizeof(a));
if (f==0)return ;
for (i=1;i<=n;i++)a[i][i]=1;
}
matrix operator*(const matrix&fun)const{
matrix ans(0,n);
long long i,j,k;
for (i=1;i<=n;i++){
for (k=1;k<=n;k++){
if (a[i][k])for (j=1;j<=n;j++){
ans.a[i][j]+=a[i][k]*fun.a[k][j];
}
}
}
return ans;
}
matrix qpow(long long x)const{
matrix ans(1,n);
matrix tmp=(*this);
while (x){
if (x&1)ans=ans*tmp;
tmp=tmp*tmp;
x>>=1;
}
return ans;
}
};
int main(){
long long i,j,n,m,k,x,y;
char fun;
while (scanf("%lld%lld%lld",&n,&m,&k)!=EOF&&n+m+k){
matrix ans(1,n+1);
for (i=1;i<=k;i++){
scanf("%s%lld",&fun,&x);
if (fun=='g')ans.a[x][n+1]++;
else if (fun=='e'){
for (j=1;j<=n+1;j++){
ans.a[x][j]=0;
}
}
else {
scanf("%lld",&y);
for (j=1;j<=n+1;j++)swap(ans.a[x][j],ans.a[y][j]);
}
}
ans=ans.qpow(m);
for (i=1;i<=n;i++){
printf("%lld%c",ans.a[i][n+1],i==n?'\n':' ');
}
}
}
相关文章推荐
- poj 3735 Training little cats(矩阵构造,快速幂)
- POJ 3735 Training little cats 解题报告(矩阵构造+快速幂优化)
- poj 3735 Training little cats 构造矩阵+稀疏矩阵加速连乘+矩阵快速幂
- poj 3735 Training little cats(矩阵快速幂,模版更权威,这题数据很坑)
- 矩阵快速幂 POJ 3735 Training little cats
- poj 3735 Training little cats (矩阵快速幂)
- poj 3735 Training little cats(矩阵快速幂)
- POJ 3735 Training little cats(矩阵快速幂)
- POJ 3735 Training little cats (矩阵快速幂)
- (矩阵快速幂 1.3)POJ 3735 Training little cats(交换矩阵的某一列)
- POJ 3735 Training little cats(矩阵快速幂)
- poj 3735 Training little cats(构造矩阵)
- poj_3735_Training little cats(矩阵快速幂)
- POJ 3735 Training little cats(矩阵快速幂)
- POJ 3735 Training little cats(矩阵快速幂)
- poj-3735-Training little cats-矩阵快速幂
- POJ - 3735 Training little cats(矩阵快速幂)
- poj 3735 Training little cats(构造矩阵)
- POJ 3735 Training little cats(矩阵快速幂)
- poj 3735 Training little cats 矩阵快速幂+稀疏矩阵乘法优化