NC229815. 悟道
描述
将恰好一个五百年寿元将至,元婴大能不希望陨落于算法之元神劫,因此他不想浪费太多时间玩这个游戏,希望你帮他算一算,有多少个未被虚空覆盖的坐标,初始时将异果放置在这里,如果双方都采取最优策略,元婴大能可以获胜。(
) 变为
,其中
,且不存在
满足:
输入描述
第一行两个以空格分隔的整数(
),表示空间每个维度的大小和被虚空覆盖的坐标的数量。
接下来行,每行四个以空格分隔的正整数
(
),表示第
个被虚空覆盖的坐标。
保证任意两个被虚空覆盖的坐标不相同,也就是说。
输出描述
一个非负整数,表示有多少个未被虚空覆盖的坐标满足初始时将异果放置在这里,如果双方都采取最优策略,元婴大能可以获胜。
示例1
输入:
2 0
输出:
8
说明:
第一个样例中,符合条件的坐标集合为示例2
输入:
2 2 1 1 1 1 2 2 2 2
输出:
6
说明:
第二个样例中,符合条件的坐标集合为示例3
输入:
37 0
输出:
1836504
示例4
输入:
73 3 1 1 4 5 1 4 1 1 4 5 1 4
输出:
28065919
C++(g++ 7.5.0) 解法, 执行用时: 307ms, 内存消耗: 3152K, 提交时间: 2022-10-29 11:29:08
#include <bits/stdc++.h> using namespace std; using B = bitset<200>; int main() { ios::sync_with_stdio(0), cin.tie(0); int n, m; cin >> n >> m; vector<array<int, 4>> a(m); for (auto &v : a) { for (int &x : v) { cin >> x, x--; } } sort(a.begin(), a.end(), [&](auto p, auto q) { p[3] *= -1, q[3] *= -1; return p < q; }); int ans = n * n * n * n - m; vector x(n, vector<B>(n)); for (int i = 0, ptr = 0; i < n; i++) { vector<B> y(n); for (int j = 0; j < n; j++) { B z; for (int k = 0; k < n; k++) { B b = ~(x[j][k] | y[k] | z); int lst = n; for (; ptr < m && a[ptr] < array{i, j, k, n}; ptr++) { int l = b._Find_next(a[ptr][3]); if (l < lst) x[j][k][l] = y[k][l] = z[l] = 1, ans--; l = lst = a[ptr][3]; x[j][k][l] = y[k][l] = z[l] = 0; } int l = b._Find_first(); if (l < lst) x[j][k][l] = y[k][l] = z[l] = 1, ans--; } } } cout << ans << "\n"; return 0; }
C++ 解法, 执行用时: 156ms, 内存消耗: 3256K, 提交时间: 2022-01-08 00:34:42
#include<bits/stdc++.h> using namespace std; int i,j,k,n,m,t,res,it=1; bitset<205> a[205][205],b[205],c,sb; struct SB{ int a,b,c,d; bool operator<(const SB x)const{ return (a==x.a)?((b==x.b)?((c==x.c)?(d>x.d):(c<x.c)):(b<x.b)):(a<x.a); } }s[100500]; int main() { ios::sync_with_stdio(0); cin>>n>>m; res=n*n*n*n-m; for(i=1;i<=m;i++)cin>>s[i].a>>s[i].b>>s[i].c>>s[i].d; sort(s+1,s+m+1); for(i=1;i<=n;i++){ for(j=1;j<=n;j++)b[j].set(); for(j=1;j<=n;j++){ c.set(); for(k=1;k<=n;k++){ if(i==1)a[j][k].set(); sb=(a[j][k]&b[k]&c); while(it<=m&&s[it]<(SB){i,j,k,-1}){ int l=s[it].d; t=sb._Find_next(l); if(t<=n)res--,a[j][k][t]=b[k][t]=c[t]=0; a[j][k][l]=b[k][l]=c[l]=1; for(;l<=n;l++)sb[l]=0; it++; } t=sb._Find_next(0); if(t<=n)res--,a[j][k][t]=b[k][t]=c[t]=sb[t]=0; } } } cout<<res; }