快速幂,水题
题目意思:
有个矩阵, row行, col 列。对于每一行, r[i] 表示第i行,从最开始的位置连续 r[i] 个格子,全部涂黑色。
注意,隐含的意思就是, 第i行的第 r[i] + 1 个格子是白色。
而数组 c[i] 表示的意思大致相同。
本题要点:
1、矩阵中,用1 表示黑色,0表示白色, -1 表示 可填白色和黑色。 题目问,有多少种涂色方法,就是问
有多少个格子可以填 -1 , 假设有 p 个 -1, 答案就是 2^p
2、套用快速幂模板,水题。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int MaxN = 1010;
int grid[MaxN][MaxN], r[MaxN], c[MaxN];
const long long mod = 1e9 + 7;
int row, col;
bool valid = true;
void solve()
{
memset(grid, -1, sizeof grid);
for(int i = 1; i <= row; ++i)
{
for(int j = 1; j <= r[i]; ++j)
{
grid[i][j] = 1;
}
if(r[i] + 1 <= col)
{
grid[i][r[i] + 1] = 0;
}
}
for(int i = 1; i <= col; ++i)
{
for(int j = 1; j <= c[i]; ++j)
{
if(grid[j][i] == 0)
{
valid = false;
return;
}
grid[j][i] = 1;
}
if(c[i] + 1 <= row)
{
if(grid[c[i] + 1][i] == 1)
{
valid = false;
return;
}
grid[c[i] + 1][i] = 0;
}
}
}
long long quick_pow(long long a, int p)
{
long long ans = 1;
while(p)
{
if(p & 1)
ans = ans * a % mod;
a = a * a % mod;
p >>= 1;
}
return ans;
}
int main()
{
scanf("%d%d", &row, &col);
for(int i = 1; i <= row; ++i)
scanf("%d", &r[i]);
for(int i = 1; i <= col; ++i)
scanf("%d", &c[i]);
solve();
if(!valid)
{
printf("0\n");
return 0;
}
int cnt = 0;
for(int i = 1; i <= row; ++i)
for(int j = 1; j <= col; ++j)
{
if(grid[i][j] == -1)
++cnt;
}
printf("%lld\n", quick_pow(2, cnt));
return 0;
}
/*
3 4
0 3 1
0 2 3 0
*/
/*
2
*/
/*
19 16
16 16 16 16 15 15 0 5 0 4 9 9 1 4 4 0 8 16 12
6 12 19 15 8 6 19 19 14 6 9 16 10 11 15 4
*/
/*
797922655
*/