题意:
给一个n*m的矩阵,每个小方格都可以取三种颜色。问有多少种染色方法可以使得矩阵中至少一对(x1,y1)与(x2,y2)满足
输入:
t,代表t组样例
每组样例输入n和m
输出:
染色方案数
思路:
打表 + 鸽巢原理
打表:可以手动打表(很难),也可以想办法代码进行打表
鸽巢原理:400个人一定有两个人在同一天生日(通俗易懂哈)
官方题解:
不妨假设n < m。考虑一个只有2行的矩阵。
由于我们只有3种颜色,只能产生9种不同的列组合。如果我们的列数超过9.
那根据抽屉原理,我们必定能找到相同的两列。也就是说,当 max(n,m) > 9的时候,所有的染色方案都可以产生满足条件的矩阵。
对于更小的情况,我们可以暴力搜索来算出那些不满足题设的方案数。如果担心实现的效率,也可以打表。
代码实现:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 5e6 + 5;
const ll mod = 1e9 + 7;
//打表???
ll qpow(ll a,ll b){
ll res = 1;
while(b){
if(b & 1) res = (res * a) % mod;
a = (a * a) % mod;
b >>= 1;
}
return res % mod;
}
ll data[9][9] = {0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 15, 339, 4761, 52929, 517761, 4767849, 43046721, 387420489,
0, 339, 16485, 518265, 14321907, 387406809, 460338013, 429534507, 597431612,
0, 4761, 518265, 43022385, 486780060, 429534507, 792294829, 175880701, 246336683,
0, 52929, 14321907, 486780060, 288599194, 130653412, 748778899, 953271190, 644897553,
0, 517761, 387406809, 429534507, 130653412, 246336683, 579440654, 412233812, 518446848,
0, 4767849, 460338013, 792294829, 748778899, 579440654, 236701429, 666021604, 589237756,
0, 43046721, 429534507, 175880701, 953271190, 412233812, 666021604, 767713261, 966670169,
0, 387420489, 597431612, 246336683, 644897553, 518446848, 589237756, 966670169, 968803245};
int main(){
int t;
scanf("%d",&t);
while(t--){
ll n,m;
scanf("%lld%lld",&n,&m);
if(n == 1||m == 1){
printf("0\n");
}
else if(n > 9||m > 9){
ll ans = qpow(3ll,n * m);
printf("%lld\n",ans);
}
else{
n--;//手动写二维矩阵,为了对应好,n--
m--;
ll ans1 = data[n][m] % mod;
printf("%lld\n",ans1);
}
}
return 0;
}