CSU1989-古怪的行列式-模拟
Description
这几天,子浩君潜心研究线性代数。 行列式的值定义如下:
其中,τ(j1j2…jn)为排列j1j2…jn的逆序数。
子浩君很厉害的,但是头脑经常短路,所以他会按照行列式值的定义去计算,这个行列式子浩君也还是能算对的。但是,在计算的过程中,如果出现连续三行选取的元素为83(S),83(S),82(R)的话,子浩君会忍不住拿走它们:-D,然后这三个数的乘积将被视为1,而其它数值计算不变。那么在子浩君的计算下,最后得到的行列式的值会为多少呢?
Input
数据第一行为一个整数T(T<=50)。 接下来有T组测试数据,每组数据开始有一个整数n(2<=n<=8)。 接下来有n行数字,每行有n个数字,第ith行第jth个数字代表矩阵的第ith行第jth列的数字,保证每个数字在int范围内的非负整数。
Output
输出一个整数,保证在[-(2^63-1), 2^63-1]范围内,即使在子浩君计算过程中也是。
Sample Input
4
2
1 1
0 1
3
83 1 1
0 83 1
0 0 82
3
83 1 1
0 82 1
0 0 83
3
83 1 1
0 83 1
0 1 82
Sample Output
1
1
564898
-82
Hint
例如,当子浩君遇到
a11 ∗a22∗a33∗a44 = 83 ∗ 83 ∗ 82 ∗ 1
,会计算成1 * 1 = 1,而83 * 82 * 83 * 1或者83 * 83 * 1 * 82则不会改变运算规则
思路
数据量也小,就按照计算行列式的思路做就好了,用用next_permutation()还不是美滋滋
不过注意!字典序下一个不一定和前一个的逆序数只差1!所以不能循环一次取一次反
我是暴力来的,也就每次多判断最多28次,这个时间能接受
AC代码
/**************************************
*Source : CSU1979
*Knowledge Point : ADHOC
*Author : CSUzick
**************************************/
#include <cstdio>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <stack>
#include <vector>
#include <queue>
#include <cctype>
#include <cmath>
#include <algorithm>
#include <set>
#include <bitset>
#include <map>
#define LL long long
#define mk(a,b) make_pair(a,b)
#define ULL unsigned long long
#define mem(a,n) memset(a,n,sizeof(a))
#define fread freopen("in.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)
#define N 1010
#define INF 0x3f3f3f3f
#define eps 1e-9
using namespace std;
int matri[8][8];
int per[8]={0,1,2,3,4,5,6,7};
int main()
{
int t,n;
LL sum,cur,k;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
scanf("%d",&matri[i][j]);
}
}
sort(per,per+8);
sum=0;
do{
cur=1,k=1;
for(int i=0;i<n;++i){
if(i<n-2&&matri[i][per[i]]==83&&matri[i+1][per[i+1]]==83&&matri[i+2][per[i+2]]==82){
i+=2;
}else{
cur*=matri[i][per[i]];
}
}
for(int i=1;i<n;++i){
for(int j=0;j<i;++j){
if(per[i]<per[j]){
k=-k;
}
}
}
sum+=cur*k;
}while(next_permutation(per,per+n));
printf("%lld\n",sum);
}
return 0;
}