Educational Codeforces Round 123 - D(思维题)
D. Cross Coloring
题意
$n \times m $ 的方格纸上进行 q 次操作,每次操作选择某整行 x 和某整列 y,使得行 x 和列 y 均涂上 k 种颜色中的一种。问你最终的方案数
思路
倒序考虑操作,因为对于同一行或者同一列,后面的操作覆盖前面的操作
利用数组标记某行或者某列是否被标记过,同时另外统计行列的标记数,如果说行均被标记了,那么对于列的操作就无效了,因为所有列都被覆盖了,对于列同理
详见代码,难度不高
类似题 - 2023牛客多校第四场 - L
代码
//>>>Qiansui
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x, y, sizeof(x))
#define debug(x) cout << #x << " = " << x << '\n'
#define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << '\n'
//#define int long long
using namespace std;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef pair<double, double> pdd;
/*
*/
const int maxm = 2e5 + 5, inf = 0x3f3f3f3f, mod = 998244353;
const ll INF = 0x3f3f3f3f3f3f3f3f;
void solve(){
int n, m, k, q;
cin >> n >> m >> k >> q;
vector<pii> a;
for(int i = 0; i < q; ++ i){
int x, y;
cin >> x >> y;
a.push_back({x, y});
}
vector<bool> r(n + 1, false), c(m + 1, false);
ll ans = 1, sr = n, sc = m;
for(int i = a.size() - 1; i >= 0; -- i){
int u = a[i].first, v = a[i].second;
if(!r[u] || !c[v]){
bool f = false;
if(!r[u] && sc) f = true;
if(!c[v] && sr) f = true;
if(f) ans = ans * k % mod;
if(!r[u]) -- sr;
if(!c[v]) -- sc;
r[u] = c[v] = true;
}
}
cout << ans << '\n';
return ;
}
signed main(){
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int _ = 1;
cin >> _;
while(_ --){
solve();
}
return 0;
}
本文来自博客园,作者:Qiansui,转载请注明原文链接:https://www.cnblogs.com/Qiansui/p/17720874.html