UNIQUE VISION Programming Contest 2025 Spring (AtCoder Beginner Contest 398)


A - Doors in the Center

分奇偶讨论

点击查看代码
void solve() {
    int n;
    std::cin >> n;
    if (n & 1) {
    	std::string s = std::string(n / 2, '-') + "=" + std::string(n / 2, '-');
    	std::cout << s << "\n";
    } else {
    	std::string s = std::string(n / 2 - 1, '-') + "=";
    	std::string ans = s;
    	std::reverse(s.begin(), s.end());
    	ans += s;
    	std::cout << ans << "\n";
    }
}

B - Full House 3

判断出现次数最多的两个数是否满足条件。

点击查看代码
void solve() {
    int cnt[14]{};
    for (int i = 0; i < 7; ++ i) {
    	int x;
    	std::cin >> x;
    	++ cnt[x];
    }

    std::sort(cnt, cnt + 14, std::greater<int>());
    if (cnt[0] >= 3 && cnt[1] >= 2) {
    	std::cout << "Yes\n";
    } else {
    	std::cout << "No\n";
    }
}

C - Uniqueness

题意:找一个位置它是唯一出现过的数里值最大的。

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

    int ans = -1;
    for (int i = n - 1; i >= 0; -- i) {
    	if (mp[a[i]] == 1) {
    		if (ans == -1 || a[i] > a[ans - 1]) {
    			ans = i + 1;
    		}
    	}
    }

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

D - Bonfire

题意:\((0, 0)\)处不断生成烟,每秒所有烟都会按照给出的序列移动,烟不会消失。求每个时刻\((r, c)\)这个位置有没有烟。

如果第\(i\)时刻有一团烟在\((r, c)\),那么就是有一个\([j, i]\)使得操作这个区间可以到\((r, c)\),那么用\(set\)存坐标的变化,如果当前坐标是\((x, y)\),判断有没有一个坐标是\((x - r, y - c)\)

点击查看代码
void solve() {
    int n, r, c;
    std::cin >> n >> r >> c;
    std::string s;
    std::cin >> s;
    std::set<std::pair<int, int>> set;
    int x = 0, y = 0;
    set.insert({x, y});
    std::string ans(n, '0');
    for (int i = 0; i < n; ++ i) {
    	if (s[i] == 'N') {
    		-- x;
    	} else if (s[i] == 'W') {
    		-- y;
    	} else if (s[i] == 'S') {
    		++ x;
    	} else {
    		++ y;
    	}

    	if (set.count({x - r, y - c})) {
    		ans[i] = '1';
    	}

    	set.insert({x, y});
    }

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

E - Tree Game

题意:交互题。给出一棵树,你和别人轮流加边,加边的规则是,这个边之前没有出现过,且加上这条边之后没有奇数环出现。你可以选择是先手还是后手。

每次都只能给距离是偶数的点连边。
那么把所有距离是偶数的点存下来,根据奇偶判断先手。

点击查看代码
std::pair<int, int> ask() {
	int u, v;
	std::cin >> u >> v;
	return {u, v};
}

void solve() {
    int n;
    std::cin >> n;
    std::vector<std::vector<int>> adj(n);
    for (int i = 1; i < n; ++ i) {
    	int u, v;
    	std::cin >> u >> v;
    	-- u, -- v;
    	adj[u].push_back(v);
    	adj[v].push_back(u);
    }

    std::vector d(n, std::vector<int>(n));
    for (int i = 0; i < n; ++ i) {
    	auto dfs = [&](auto & self, int u) -> void {
    		for (auto & v : adj[u]) {
    			if (d[i][v] == 0) {
    				d[i][v] = d[i][u] + 1;
    				self(self, v);
    			}
    		}
    	};

    	d[i][i] = 1;
    	dfs(dfs, i);
    }

    std::set<std::pair<int, int>> s;
    for (int i = 0; i < n; ++ i) {
    	for (int j = i + 1; j < n; ++ j) {
    		if (d[i][j] % 2 == 0) {
    			s.insert({i, j});
    		}
    	}
    }

    for (int i = 0; i < n; ++ i) {
    	for (auto & v : adj[i]) {
    		s.erase({i, v});
    	}
    }

    if (s.size() % 2 == 1) {
    	std::cout << "First" << std::endl;
    } else {
    	std::cout << "Second" << std::endl;
    	auto [u, v] = ask();F - ABCBA
    	if (u == -1) {
    		return;
    	}

    	if (u > v) {
    		std::swap(u, v);
    	}

    	-- u, -- v;

    	s.erase({u, v});
    }

    while (s.size()) {
    	std::cout << s.begin()->first + 1 << " " << s.begin()->second + 1 << std::endl;
    	s.erase(s.begin());
    	auto [u, v] = ask();
    	if (u == -1) {
    		return;
    	}

    	if (u > v) {
    		std::swap(u, v);
    	}

    	-- u, -- v;

    	s.erase({u, v});
    }
}

F - ABCBA

题意:找一个字符串,使得\(s\)是它的前缀,且这个字符串是回文,并且要求长度尽可能小。

我们要求最长的是回文的后缀,这个可以用\(hash\)

点击查看代码
void solve() {
    std::string s;
    std::cin >> s;
    int n = s.size();
    std::vector<ui64> h(n + 1), rh(n + 1), p(n + 1);
    for (int i = 0; i < n; ++ i) {
        h[i + 1] = (131 * h[i] + s[i] - 'A');
    }

    for (int i = 0; i < n; ++ i) {
        rh[i + 1] = (131 * rh[i] + s[n - 1 - i] - 'A');
    }

    p[0] = 1;
    for (int i = 0; i < n; ++ i) {
        p[i + 1] = 131 * p[i];
    }
    
    auto get = [&](std::vector<ui64> & h, int l, int r) -> ui64{
        return (h[r] - h[l] * p[r - l]);
    };

    int pos = n;
    for (int i = n; i >= 1; -- i) {
    	if (get(h, n - i + 1, n) == get(rh, 1, i)) {
    		pos = n - i;
    		break;
    	}
    }

    std::string ans = s.substr(0, pos);
    std::reverse(ans.begin(), ans.end());
    ans = s.substr(0, pos) + s.substr(pos) + ans;
    std::cout << ans << "\n";
}
posted @ 2025-03-22 21:54  maburb  阅读(89)  评论(0)    收藏  举报