Warm UP for Changsha

地址 :http://122.207.68.93:9090/csuacmtrain/contest/view.action?cid=114#overview

UVA 12653

矩阵快速幂 来递推

#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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值