SGU 197 Nice Patterns Strike Back || ZOJ 2317 Nice Patterns Strike Back

题目链接~~>

做题感悟:做了这题感觉学习了不少东西,首先是关于状态压缩推公式学会了。

解题思路:

构造矩阵: B[ i ][ j ] (i , j 为状态,0 <= i ,j  <= (1<<m) - 1 ) , 如果 B[ i ] [ j ]  等于 1 代表状态 i 与状态 j 相互兼容(i , j 可以在相邻两行),如果为 0 代表不可以相邻,还要有一个原始矩阵 A ,(1<<m)-1 行 ,1列的矩阵  ,代表第一行各种状态的方案数,这样 B *  A 就得到了第二行各种状态的方案数,so ~ > A^( n - 1) *
B 就得到了第 n 行的方案数,最后将最终矩阵相加就是总的方案数。因为这题指数比较大,so~>需要大数模拟除 2 的操作就可以了

代码:

#include<iostream>
#include<sstream>
#include<map>
#include<cmath>
#include<fstream>
#include<queue>
#include<vector>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<stack>
#include<bitset>
#include<ctime>
#include<string>
#include<cctype>
#include<iomanip>
#include<algorithm>
using namespace std  ;
#define INT  long long int
#define L(x)  (x * 2)
#define R(x)  (x * 2 + 1)
const int INF = 0x3f3f3f3f ;
const double esp = 0.0000000001 ;
const double PI = acos(-1.0) ;
const int MY = 1400 + 5 ;
const int MX = 1005 + 5 ;
int S ,m ;
int d[MX] ;
INT mod ;
struct STR
{
    int n ,d[MX] ;
    STR()
    {
        n = 0 ;
        memset(d ,0 ,sizeof(d)) ;
    }
    STR operator - (int x)
    {
       STR s ;
       s.n = n ;
       for(int i = n - 1 ;i >= 0 ; --i)
        if(d[i])
        {
            d[i]-- ;
            for(int j = i+1 ;j < n ; ++j)
                d[j] = 9 ;
                break ;
        }
       if(d[0] == 0)
       {
           for(int i = 1 ;i < n ; ++i)
              s.d[i-1] = d[i] ;
              s.n-- ;
       }
       else
          for(int i = 0 ;i < n ; ++i)
                 s.d[i] = d[i] ;
       return s ;
    }
    STR operator >> (int x)
    {
       STR s ;
       int a[MX] ,num = 0 ,sum = 0 ;
       for(int i = 0 ;i < n ; ++i)
       {
           sum = sum*10 + d[i] ;
           if(sum >= 2)
           {
               a[num++] = sum / 2 ;
               sum = sum%2 ;
           }
           else if(num)
               a[num++] = 0 ;
       }
       for(int i = 0 ;i < num ; ++i)
           s.d[i] = a[i] ;
           s.n = num ;
       return s ;
    }
    bool operator &(int x)
    {
        if(d[n-1]&1)  return true ;
        return false ;
    }
} ;
struct M
{
    INT p[33][33] ;
    M()
    {
        memset(p ,0 ,sizeof(p)) ;
    }
    void init()
    {
        for(int i = 0 ;i < S ; ++i)
          p[i][i] = 1 ;
    }
} ;
bool judge(int x ,int y)
{
    for(int i = 0 ;i < m-1 ; ++i)
       if(((x&(1<<i)) && (x&(1<<(i+1))) && (y&(1<<i)) && (y&(1<<(i+1))))||
         (!(x&(1<<i)) && !(x&(1<<(i+1))) && !(y&(1<<i)) && !(y&(1<<(i+1)))))
               return   false ;
    return   true ;
}
M Pre() // 构造矩阵
{
    M c ;
    for(int i = 0 ;i < S ; ++i)
      for(int j = i ;j < S ; ++j)
         if(judge(i ,j))
              c.p[i][j] = c.p[j][i] = 1 ;
    return c ;
}
M operator * (const M& a ,const M& b)  // 矩阵乘法
{
    M c ;
    for(int i = 0 ;i < S ; ++i)
      for(int k = 0 ;k < S ; ++k)
        if(a.p[i][k])
          for(int j = 0 ;j < S ; ++j)
             c.p[i][j] = (c.p[i][j] + a.p[i][k]*b.p[k][j]) %mod ;
    return c ;
}
M pow(M a ,STR k)  // 快速幂
{
    M b ;
    b.init() ;
    while(k.n)
    {
        if(k&1)
            b = b * a ;
        a = a * a ;
        k = k>>1 ;
    }
    return b ;
}
int main()
{
    char str[MX] ;
    while(cin>>str>>m>>mod)
    {
        S = (1<<m) ;       // 总状态
        STR s ;
        for(int i = 0 ;i < strlen(str) ; ++i)
           s.d[i] = str[i]-'0' ;
        s.n = strlen(str) ;
        s = s - 1 ;
        M c = Pre() ;
        M b = pow(c ,s) ;
        INT ans = 0 ;
        for(int i = 0 ;i < S ; ++i)
          for(int j = 0 ;j < S ; ++j)
             ans = (ans + b.p[i][j]) %mod ;
        cout<<ans<<endl ;
    }
    return 0 ;
}
时间: 2024-07-31 11:55:50

SGU 197 Nice Patterns Strike Back || ZOJ 2317 Nice Patterns Strike Back的相关文章

ZOJ 2317 Nice Patterns Strike Back

题意 在一个N*M的矩阵中给每个格子染上黑白色,要求任意一个2*2的矩阵颜色不能一样,N<=10^100,m<=5. 解法 首先看这个题,若n和m很小,则我们可以直接用状态压缩乱搞,但是N太大了,显然只能是快速幂(看到这个题的第一感觉),然后就是构造矩阵,在矩阵快速幂,不说了,网上说的比我好的太多了.这个题我并不想写这个博客的,但是由于它是我第一个java程序(虽然以前写过一个,不过那个是a+b问题),所以纪念一下 import java.util.*; import java.math.*;

zoj 2317 Nice Patterns Strike Back(矩阵乘法)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1317 给出一个n*m的矩阵(n <= 10^100, m <= 5),对于2*2的子方格若全是黑色或全是白色的是非法的,用黑白两色去染n*m的方格,问共有多少种合法的染色方案. 构造出转移矩阵,上一行向下一行的转移矩阵,因为m<=5,每行最多有32个状态,可以进行状态压缩构造出一个32*32的转移矩阵A,A[i][j] = 1表示上一行i状态可以向下一行的j状态转移,

SGU 197.Nice Patterns Strike Back

时间限制:0.5s 空间限制:6M 题意: 给出长n(n<=10^100)和宽m(m<=5)的地面,铺上黑色和白色的地板,使得没有任意一个2*2大小的地面铺同种颜色的方案数是多少. Solution: 状态压缩,一个数字的对应为01分别代表铺白色和黑色地板,对于每一列有(1<<m)种状态. 我们可以构造一个矩阵,mat[i][j]代表,第一列是状态是i,第二列是j的方案数,显然mat[i][j]不是0就是1,而且很容易判断构造. 然后我们只要对这个矩阵进行快速幂运算,幂为(n-1)

【ZOJ】Nice Patterns Strike Back(矩阵快速乘法)

dp[[i][j] = sum(dp[i - 1][k]) (k -> j) 状态方程,因为N很大而M很小,所以第一时间可以想到矩阵优化 可能之前没做过类似的题被卡的很厉害. 另外用C++写大数真心麻烦.. #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 45; const int maxd = 30005; char n[ma

ASC #1

开始套题训练,第一套ASC题目,记住不放过每一题,多独立思考. Problem A ZOJ 2313 Chinese Girls' Amusement 循环节 题意:给定n,为圆环长度,求k <= n/2,从1出发,每次顺时针方向走k步,即1->k+1->2*k+1,直到遇到一个已经走过的点结束,要求最终把所有点访问一遍,最后回到1,使得k尽量大. 代码: Problem B ZOJ 2314 Reactor Cooling 无源汇上下界网络流 题意:经典题,有上下界无源无汇的可行流,对

Cocoa Design Patterns

Book Description This is the Rough Cut version of the printed book. Much of the technology embodied by Apple's Cocoa software development frameworks have been in commercial use since 1988, and in spite of many years of use, the Cocoa frameworks are s

Design Patterns Example Code (in C++)

Overview Design patterns are ways to reuse design solutions that other software developers have created for common and recurring problems. The design patterns on this page are from the book Design Patterns, Elements of Reusable Object-Oriented Softwa

Learning JavaScript Design Patterns -- A book by Addy Osmani

Learning JavaScript Design Patterns A book by Addy Osmani Volume 1.6.2 Tweet Copyright © Addy Osmani 2015. Learning JavaScript Design Patterns is released under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 unported license. It

Design Principles from Design Patterns

Leading-Edge Java A Conversation with Erich Gamma, Part III by Bill Venners June 6, 2005 Erich Gamma lept onto the software world stage in 1995 as co-author of the best-selling book Design Patterns: Elements of Reusable Object-Oriented Software (Addi