ABC120
ABC120
UnionFindがわからないなら以下を見ると良いかもしれない。
UnionFindの解説 : B: Union Find - AtCoder Typical Contest 001 | AtCoder
A問題
方針
python
#python3
a, b, c = map( int, input().split() )
print( min(b//a,c) )
C++
//C++
#include<iostream>
#include<algorithm>
int main() {
int a, b, c;
std::cin >> a >> b >> c;
std::cout << std::min(b/a ,c) << "\n";
return 0;
}
B問題:
python
#python 3
a, b, k = map(int,input().split())
ans = []
for i in range(1,min(a,b)+1):
if a%i ==0 and b%i == 0:
ans.append(i)
print(ans[-1*k])
C++
//cpp14
#include<iostream>
#include<vector>
#include<algorithm>
int main() {
int a, b, k;
std::cin >> a >> b >> k;
std::vector<int> v;
auto mv = std::min(a, b);
for (int i{1}; i <= mv; ++i) {
if (a%i == 0 &&; b%i == 0)
v.emplace_back(i);
}
std::cout << *(v.rbegin() + k-1) << "\n";
return 0;
}
C問題:
蛇足
python
#python 3
s = input()
n = len(s)
stack = [ s[0] ]
rem = 0
ss = len(stack)
for i in range(1,n):
if ss==0 or stack[-1] == s[i]:
stack.append(s[i])
ss += 1
continue
stack.pop()
ss -= 1
i+=1
rem +=2
print(rem)
C++
//cpp14
#include<iostream>
#include<vector>
#include<string>
int main() {
std::string s;
std::cin >> s;
std::vector<char> stack_;
stack_.reserve(s.size());
auto count = 0;
for (const auto&e : s) {
if (stack_.empty()) {
stack_.push_back(e);
continue;
}
if (stack_.back() != e) {
stack_.pop_back();
count += 2;
}
else {
stack_.push_back(e);
}
}
std::cout << count << "\n";
return 0;
}
C++ 別解
//cpp14 別解
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
int main() {
std::string s;
std::cin >> s;
decltype(s.size()) zeros = std::count(s.begin(), s.end(), '0');
std::cout << 2*std::min(zeros, s.size() - zeros) << "\n";
return 0;
}
D問題:
方針
size: root: __link__:実装概要、多分だけど
再帰難しい
python
# python 3
class dset:
def __init__(self,n):
self.par = [-1]*n
def size(self,n):
return -self.par[self.root(n)]
def root(self,n):
if self.par[n]<0:
return n
else:
self.par[n] = self.root(self.par[n])
return self.par[n]
def same(self, a, b):
return self.root(a) == self.root(b)
def __link__(self,a,b):
if a == b:
return
if self.size(a) < self.size(b):
a, b = b, a
self.par[a] += self.par[b]
self.par[b] = a
def unite(self,a,b):
self.__link__(
self.root(a)
,self.root(b)
)
def main():
n, m = map(int, input().split() )
ins = [ list( map(int,input().split()) ) for i in range(m) ]
ds = dset(n)
ans = [0]*m
ans[-1] = n*(n-1)//2
for i in range(m-1,0,-1):
ans[i-1] = ans[i]
a,b = ins[i]
a -= 1
b -= 1
# print(ins[i])
# print( (ds.root(a),ds.root(b)) )
if not ds.same(a,b):
x = ds.size(a)
y = ds.size(b)
#print((x,y))
ans[i-1] -= x*y
ds.unite(a,b)
for e in ans:
print(e)
if __name__ == '__main__':
main()
C++
//cpp14
#include<iostream>
#include<vector>
#include<algorithm>
using sll = signed long long;
using ui = long int;
class disjoint_set {
std::vector<int> p;
auto link(int x, int y) {
//x = find(x);
//y = find(y);
if(x==y)
return false;
if ( size(x) < size(y) )
std::swap(x, y);
p[x] += p[y];
p[y] = x;
return true;
}
public:
disjoint_set():p{}{}
disjoint_set(int size_) :
p{}{
p.resize(size_, int{-1});
}
auto find(int x)
->decltype(p)::value_type {
return p[x] < 0 ?
x : p[x] = find(p[x]);
}
auto same(int x, int y) {
return
find(x) == find(y);
}
auto unite(int x, int y) {
this->link(find(x), find(y));
}
auto size(int x)
->decltype(p)::value_type{
return -p[ this->find(x) ];
}
};
int main() {
int n, m;
std::cin >> n >> m;
std::vector< std::pair<int, int> > vp;
disjoint_set ds{ n };
vp.resize(m);
for (int i{}; i < m; ++i) {
int a, b;
std::cin >> a >> b;
vp[i] = std::make_pair(a-1, b-1);
}
auto it = std::rbegin(vp);
auto end_ = std::rend(vp);
auto ansi = sll{ n } *(n - 1) / 2;
std::vector<sll> ans{};
ans.resize(m, 0);
ans[m - 1] = ansi;
for (int i{m-1}; i > 0; --i) {
auto a = it->first;
auto b = it->second;
ans[i-1] = ans[i];
// std::cout << " ab " << a+1 << " " << b+1 << "\n";
if (!ds.same(a, b)) {
auto x = ds.size(a);
auto y = ds.size(b);
ans[i-1] -= x * y;
ds.unite(a, b);
// std::cout <<" xy "<< x << " " << y << "\n";
if (ans[i-1] < 0 )
ans[i-1] = 0;
}
++it;
}
for (auto&e : ans)
std::cout << e << "\n";
return 0;
}
とりあえず現在の限界は、今回のD問題が解けないくらい これ以上レートを上げていくということが、 このUnionFindを平然と実装できる人達と競争するということなら、現状の能力ではかなり厳しいと感じる UnionFindくらい難しいと何も考えずに書けるものでもない。 参考にしたUnionFindを書いた人は賢いやり方をしていてなかなかわからなかった。感想
残念な失敗が多くて厳しい
経路圧縮やランクによる効率化で処理が増えても複雑になっていくのを理解できるか、再帰を考えられるかが大事なんだろう。
今回はコンテスト後に復習をかねてもう一度、コンテスト時に用いた言語ではない言語で書きなおしたので、A-Dまでpython3とC++のコードがある。
今更だけど載せるのってC以上の問題だけで良い気がする。
書き方も色々試してみる。今回はmarkdown。
コード載せる時に気づいたけどこれは正規の挙動なのか。
コード内でマークダウン効いたり改行でspan出たり何とかならないのかね。
<details>tagの中にdivを入れるのは、展開後の文章にmarkdownを適用するとき。