列表

详情


NC229815. 悟道

描述

本题有特殊的空间限制。

元婴大能贪图恶堕的魔法少女美色,强行进行双修,企图悟出算法大道。为此,他们正在进行一个小小的游戏。

具体来说,元婴大能创造了一个 的四维坐标空间,并在其中一个坐标放置一个异果。两人交替进行操作,元婴大能先手,每次可以将异果沿一个维度向小的方向移动,如果这一维的坐标是 1 则不能选择这一维,无法移动的一方会输掉游戏,另一方取得胜利。

受到界外星海的影响,m 个坐标被虚空覆盖,异果初始不能被放置在这些坐标上,移动过程中不能停留在这些坐标上,也不能越过这些坐标。例如在没有坐标被虚空覆盖的情况下可以从 (1,2,3,4) 移动到 (1,2,3,2),但是如果 (1,2,3,3) 被虚空覆盖,那么就不能从 (1,2,3,4) 移动到 (1,2,3,2)

形式化地说,设 m 个被虚空覆盖的坐标组成的集合为 S,假设当前异果位于 (x_1,x_2,x_3,x_4),那么一次操作如下:
将恰好一个 x_i () 变为 x_i',其中 ,且不存在 满足:


五百年寿元将至,元婴大能不希望陨落于算法之元神劫,因此他不想浪费太多时间玩这个游戏,希望你帮他算一算,有多少个未被虚空覆盖的坐标,初始时将异果放置在这里,如果双方都采取最优策略,元婴大能可以获胜。

输入描述

第一行两个以空格分隔的整数 n,m (),表示空间每个维度的大小和被虚空覆盖的坐标的数量。

接下来 m 行,每行四个以空格分隔的正整数 (),表示第 i 个被虚空覆盖的坐标。

保证任意两个被虚空覆盖的坐标不相同,也就是说

输出描述

一个非负整数,表示有多少个未被虚空覆盖的坐标满足初始时将异果放置在这里,如果双方都采取最优策略,元婴大能可以获胜。

示例1

输入:

2 0

输出:

8

说明:

第一个样例中,符合条件的坐标集合为 \{(1,1,1,2),(1,1,2,1),(1,2,1,1),(1,2,2,2),(2,1,1,1),(2,1,2,2),(2,2,1,2),(2,2,2,1)\}

示例2

输入:

2 2
1 1 1 1
2 2 2 2

输出:

6

说明:

第二个样例中,符合条件的坐标集合为 \{(1,1,2,2),(1,2,1,2),(1,2,2,1),(2,1,1,2),(2,1,2,1),(2,2,1,1)\}

示例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;
}

上一题