地址 :http://122.207.68.93:9090/csuacmtrain/contest/view.action?cid=114#overview
矩阵快速幂 来递推
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL MOD = 1000000;
struct Mat{
LL a[2][2];
}One={1,0,0,1};
LL N , K ,L;
Mat operator *(const Mat&a , const Mat&b){
Mat ret;
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
LL tmp = 0;
for(int k = 0;k<2;k++)
tmp += a.a[i][k]*b.a[k][j];
ret.a[i][j] = tmp % MOD;
}
}
return ret;
}
Mat pow_mod(Mat a,LL b){
Mat ans = One;
while(b){
if(b&1) ans = ans*a;
a = a*a;
b>>=1;
}
return ans;
}
int main()
{
while(scanf("%lld%lld%lld",&N,&K,&L)!=EOF){
Mat a = (Mat){K%MOD,L%MOD,1,0};
Mat tmp = pow_mod(a,N/5);
LL ans = (tmp.a[1][0]*(K%MOD) + tmp.a[1][1])%MOD;
printf("%06lld\n",ans);
}
return 0;
}
分析:
不管经过怎样的交换, 原来在同一行的依旧会在同一行 ; 原来在同一列的依旧会在同一列!!
即整个矩阵总共有A(R,R)*A(C,C)种排列方式,每种方式仅由一行+一列唯一确定!!
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 310;
struct POS{
int x,y;
}p[maxn*maxn];
int R , C , N;
bool check(){
if(R==1 || C==1) return true;
for(int i=0;i<R;i++){
int t=i*C+1;
for(int j=1;j<C;j++){
if(p[t].x != p[t+j].x) return false;
}
}
for(int j=0;j<C;j++){
int t = j+1;
for(int i=1;i<R;i++){
if(p[t+i*C].y != p[t].y) return false;
}
}
return true;
}
int A[maxn] , An ;
int Steps(){
int ans = 0;
bool ok=false;
while(!ok){
ok = true;
for(int i=0;i<An;i++){
if(A[i]==i) continue;
int t =A[i];
ok = false;
ans++ , swap(A[i] , A[t]);
}
}
return ans;
}
int main()
{
while(scanf("%d%d",&R,&C)!=EOF){
int x ;
N = R*C;
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
scanf("%d",&x);
p[x] = (POS){i,j};
}
}
if(!check()){
puts("*"); continue;
}
int ans =0;
for(int i=1;i<=C;i++){
A[p[i].y] = i-1;
}
An = C;
ans += Steps();
for(int t=1,j=0;j<R;j++ , t+=C){
A[p[t].x] = j;
}
An = R;
ans += Steps();
printf("%d\n",ans);
}
return 0;
}