VP TOYOTA SYSTEMS Programming Contest 2024(AtCoder Beginner Contest 377)


A - Rearranging ABC

点击查看代码
void solve() {
    int cnt[26]{};
    std::string s;
    std::cin >> s;
    for (auto & c : s) {
    	++ cnt[c - 'A'];
    }

    if (cnt[0] == cnt[1] && cnt[1] == cnt[2] && cnt[2] == 1) {
    	std::cout << "Yes\n";
    } else {
    	std::cout << "No\n";
    }
}


B - Avoid Rook Attack

题意:棋盘上有n个棋子,每个棋子都能吃到所在行列的格子。问有多少格子不会被吃。

记录被吃的行和列。一个格子不会被吃那么它所在的行列都不会被吃。

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

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

    int ans = 0;
    for (int i = 0; i < n; ++ i) {
    	for (int j = 0; j < n; ++ j) {
    		ans += row[i] == 0 && col[j] == 0;
    	}
    }

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

C - Avoid Knight Attack

题意:棋盘上有n个棋子,棋子是象棋里马的走法。问有多少格子不会被吃。

把被吃的格子用set存下来。

点击查看代码
void solve() {
	int n, m;
	std::cin >> n >> m;
	const int dx[] = {-2, -1, 1, 2, 2, 1, -1, -2}, dy[] = {1, 2, 2, 1, -1, -2, -2, -1};
	std::set<std::pair<int, int>> s;
	for (int i = 0; i < m; ++ i) {
		int x, y;
		std::cin >> x >> y;
		-- x, -- y;
		s.insert({x, y});
		for (int j = 0; j < 8; ++ j) {
			int nx = x + dx[j], ny = y + dy[j];
			if (nx < 0 || nx >= n || ny < 0 || ny >= n) {
				continue;
			}

			s.insert({nx, ny});
		}
	}    

	std::cout << (i64)n * n - (int)s.size() << "\n";
}

D - Many Segments 2

题意:有n个区间,求有多少区间不包含其中任意一个区间。值域为[1,m]

把每个右端点对应的左端点存下来。然后枚举右端点,这个右端点可以往左取到的地方就是前面所有区间的l的最大值。

点击查看代码
void solve() {
    int n, m;
    std::cin >> n >> m;
    std::vector<std::vector<int>> R(m + 1);
    for (int i = 0; i < n; ++ i) {
    	int l, r;
    	std::cin >> l >> r;
    	R[r].push_back(l);
    }

    i64 ans = 0;
    int l = 0;
    for (int r = 1; r <= m; ++ r) {
    	for (auto & p : R[r]) {
    		l = std::max(l, p);
    	}

    	ans += r - l;
    }

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

E - Permute K times 2

题意:给你一个排列,每次使得pi=ppi。问进行k次后的排列是什么。

如果按ipi建边,那么因为是一个排列,每个点恰好有一个出度一个入度,就会形成若干个环。这些环不管操作几次都是这些数。于是我们观察每一个环的变化。跳一次变成ppi,二次变成ppppi,那么发现每个点走了2k次。

点击查看代码
void solve() {
    int n;
    i64 k;
    std::cin >> n >> k;
    std::vector<int> p(n);
    for (int i = 0; i < n; ++ i) {
    	std::cin >> p[i];
    	-- p[i];
    }

    auto power = [&](int a, i64 b, int m) -> int {
    	int res = 1;
    	for (; b; b >>= 1, a = (i64)a * a % m) {
    		if (b & 1) {
    			res = (i64)res * a % m;
    		}
    	}

    	return res;
    };

    std::vector<int> st(n), ans(n);
    for (int i = 0; i < n; ++ i) {
    	if (!st[i]) {
    		int j = i;
    		std::vector<int> a;
    		while (!st[j]) {
    			st[j] = 1;
    			a.push_back(j);
    			j = p[j];
    		}

    		int m = a.size();
    		int d = power(2, k, m);	

    		for (int i = 0; i < m; ++ i) {
    			ans[a[i]] = p[a[(i + d - 1 + m) % m]];
    		}
    	}
    }

    for (int i = 0; i < n; ++ i) {
    	std::cout << ans[i] + 1 << " \n"[i == n - 1];
    }
}

G - Edit to Match

题意:依次输入n个字符串,对于第i个字符串,你可以每次花1的代价删除最后一个字符,或者在最后面加一个字符。问让第i个字符串和前面某一个字符串相等的最少代价。

建立一棵字典树,对于字典树的每一个节点p,记f[p]为前缀匹配到了p,还需要往后面加多少字符串可以和已有的字符串相等的最小代价。那么每次插入时到一个节点就看要删几个字符到这个前缀,然后加上f[p]。同时把插入时遇到的p存下来,然后从后往前更新。

点击查看代码
const int TrieN = 1e6 + 5;
int trie[TrieN][26], f[TrieN * 26];
struct Trie {
	int idx;
	Trie() {
		idx = 0;
	}

	int newNode() {
		idx += 1;
		memset(trie[idx], 0, sizeof trie[idx]);
		f[idx] = 1e9;
		return idx;
	}

	int insert(const std::string & s) {
		int p = 0;
		std::vector<int> a;
		int res = 1e9;
		int len = s.size();
		for (auto & c : s) {
			int x = c - 'a';
			if (!trie[p][x]) {
				trie[p][x] = newNode();
			}

			p = trie[p][x];
			-- len;
			res = std::min(res, f[p] + len);
			a.push_back(p);
		}

		int n = a.size();

		f[a[n - 1]] = 0;
		for (int i = n - 2; i >= 0; -- i) {
			f[a[i]] = std::min(f[a[i]], f[a[i + 1]] + 1);
		}

		return res;
	}
};

void solve() {
    int n;
    std::cin >> n;
    Trie tr;
    for (int i = 0; i < n; ++ i) {
    	std::string s;
    	std::cin >> s;
    	std::cout << std::min((int)s.size(), tr.insert(s)) << "\n";
    }
}
posted @   maburb  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示