VP Educational Codeforces Round 68 (Rated for Div. 2)


A. Remove a Progression

题意:\([1, n]\)排成一行,每次删掉第\(i\)个数,求最后第\(x\)个数是谁。

模拟发现偶数都会留下。所以答案就是\(x\times 2\)

点击查看代码
void solve() {
    int n, x;
    std::cin >> n >> x;
    std::cout << x * 2 << "\n";
}

B. Yet Another Crosses Problem

题意:一个矩阵,判断需要填多少数才能满足一个\((x, y)\)使得第\(x\)\(y\)列都被填满。

记录每行填了多少和每列填了多少,然后对于每个\((x, y)\)讨论即可。

点击查看代码
void solve() {
    int n, m;
    std::cin >> n >> m;
    std::vector<std::string> s(n);
    for (int i = 0; i < n; ++ i) {
    	std::cin >> s[i];
    }

    std::vector<int> row(n), col(m);
    for (int i = 0; i < n; ++ i) {
    	for (int j = 0; j < m; ++ j) {
    		if (s[i][j] == '*') {
    			row[i] ++ ;
    			col[j] ++ ;
    		}
    	}
    }

    int ans = n + m;
    for (int i = 0; i < n; ++ i) {
    	for (int j = 0; j < m; ++ j) {
    		ans = std::min(ans, n + m - 1 - (row[i] + col[j]) + (s[i][j] == '*'));
    	}
    }

    std::cout << ans << "\n";
}

C. From S To T

题意:三个字符串,\(s, t, p\),需要把\(s\)变成\(t\),可以把\(p\)中任意字符插到\(s\)任意位置。

从前往后匹配,\(s\)能匹配就匹配,不能就从\(p\)拿。如果最后\(s\)有多余的也不行。

点击查看代码
void solve() {
    std::string s, t, p;
    std::cin >> s >> t >> p;
    int n = s.size(), m = t.size();
    std::array<int, 26> cnt{};
    for (auto & c : p) {
    	++ cnt[c - 'a'];
    }

    int i = 0, j = 0;
    for (; j < m; ++ j) {
    	if (s[i] == t[j]) {
    		++ i;
    	} else if (cnt[t[j] - 'a'] > 0) {
    		-- cnt[t[j] - 'a'];
    	} else {
    		std::cout << "NO\n";
    		return;
    	}
    }

    if (i != n) {
    	std::cout << "NO\n";
    } else {
    	std::cout << "YES\n";
    }
}

D. 1-2-K Game

题意:博弈题。每次选\(1, 2, k\)三种数,谁先使得和为\(n\)谁赢。

打表发现如果\(k\)不是\(3\)的倍数,则\(n\)\(3\)的倍数就输。如果\(k\)\(3\)的倍数,则判断\(n \% (k + 1)\)的值,如果不是\(k\)且是\(3\)的倍数则输。

点击查看代码
void solve() {
    int n, k;
    std::cin >> n >> k;
    if (k % 3 == 0) {
    	n = n % (k + 1);
    	if (n != k && n % 3 == 0) {
    		std::cout << "Bob\n";
    	} else {
    		std::cout << "Alice\n";
    	}
    } else {
    	if (n % 3 == 0) {
    		std::cout << "Bob\n";
    	} else {
    		std::cout << "Alice\n";
    	}
    }
}

E. Count The Rectangles

题意:\(n\)条平行于坐标轴的线段。求题目凑成的矩形数。

把平行于\(x\)轴的和平行于\(y\)轴的分开存。然后\(x\)轴按\(y\)坐标从小到大排序。\(y\)坐标按大的\(y\)排序。

那么可以枚举矩形的下边和上边,每次把\(y\)轴平行的线段中和下边相交的用队列存。然后枚举上边,因为已经按较大的\(y\)排序,所以可以把和上边不相交的弹出。用树状数组维护就行。假设和上边下边相交的有\(cnt\)个,那么就有\(\frac{cnt\times (cnt-1)}{2}\)个矩形。

点击查看代码
template <class T>
struct Fenwick {
    int n;
    std::vector<T> tr;

    Fenwick(int _n) {
        init(_n);
    }

    void init(int _n) {
        n = _n;
        tr.assign(_n + 1, T{});
    }

    void add(int x, const T &v) {
        for (int i = x; i <= n; i += i & -i) {
            tr[i] = tr[i] + v;
        }
    }

    T query(int x) {
        T res{};
        for (int i = x; i; i -= i & -i) {
            res = res + tr[i];
        }
        return res;
    }

    T sum(int l, int r) {
        return query(r) - query(l - 1);
    }
};

void solve() {
    int n;
    std::cin >> n;
    using A = std::array<int, 3>;
   	std::vector<A> X, Y;
   	const int D = 5001;
   	for (int i = 0; i < n; ++ i) {
   		int x1, y1, x2, y2;
   		std::cin >> x1 >> y1 >> x2 >> y2;
   		x1 += D; y1 += D; x2 += D; y2 += D;
   		if (x1 == x2) {
   			if (y1 > y2) {
   				std::swap(y1, y2);
   			}
   			Y.push_back(A{x1, y1, y2});
   		} else {
   			if (x1 > x2) {
   				std::swap(x1, x2);
   			}
   			X.push_back(A{y1, x1, x2});
   		}
   	}

   	std::ranges::sort(X);
   	std::ranges::sort(Y, [&](A & a, A & b) {
   		return a[2] < b[2];
   	});

   	i64 ans = 0;
   	for (int i = 0; i < X.size(); ++ i) {
   		Fenwick<int> tr(D * 2);
   		std::queue<A> q;
   		for (auto & [x, y1, y2] : Y) {
   			if (y1 <= X[i][0]) {
   				tr.add(x, 1);
   				q.push(A{x, y1, y2});
   			}
   		}

   		for (int j = i + 1; j < X.size(); ++ j) {
   			while (q.size() && q.front()[2] < X[j][0]) {
   				tr.add(q.front()[0], -1);
   				q.pop();
   			}

   			int l = std::max(X[i][1], X[j][1]), r = std::min(X[i][2], X[j][2]);
   			if (l <= r) {
	   			i64 cnt = tr.sum(l, r);
	   			ans += cnt * (cnt - 1) / 2;
   			}
   		}
   	}

   	std::cout << ans << "\n";
}
posted @ 2025-04-25 15:53  maburb  阅读(20)  评论(0)    收藏  举报