CF #134 A~D
A
SBT,直接搜索即可
int n, ans ;
int x[N], y[N], vis[N] ;
void dfs(int i) {
vis[i] = 1 ;
rep(j, 1, n)
if (!vis[j] && (x[i] == x[j] || y[i] == y[j]))
dfs(j) ;
}
signed main() {
scanf("%d", &n) ;
rep(i, 1, n) scanf("%d%d", &x[i], &y[i]) ;
rep(i, 1, n)
if (!vis[i]) {
ans++ ;
dfs(i) ;
}
printf("%d\n", ans - 1) ;
return 0 ;
}
B
这个题蛮有意思的
刚开始看还没什么思路
然后观察一下就大概知道了
首先枚举结束之后另外一个数的值是什么
然后考虑这种状态是怎么达到的
假如当前的状态为 \([a,b](a<b)\)
\(1\) 次操作我们可以达到 \([b,a+b]\)
\(2\) 次操作我们可以到达 \([b,a+2*b]\) 和 \([a+2*b,a+b]\)
any idea?
是不是有点像辗转相减,???
然后大概就会了吧
模拟 \(gcd\) 的过程
从 \(gcd(a,b)\) 变成 \(gcd(b,a\%b)\) 的 \(mistake~size\) 就是 \((a/b-1)\) (特判 \(b=1\) 的情况)
转移时的还要维护一个步数,每次加 \(a/b\)
然后就 \(AC\) 了
这个 \(Div2D\) 质量还不错,(大雾)
int n, r, cur, mst, ans, ansid ;
int gcd(int a, int b) {
if (!b) return a ;
cur += a / b ;
mst += max(0, a / b - 1) ;
if (b == 1 && a > 1) mst-- ;
return gcd(b, a % b) ;
}
int col = 0 ;
char op[] = {'T', 'B'} ;
void solve(int a, int b) {
if (b == 0) return ;
solve(b, a % b) ;
if (b == 1 && a > 1) {
putchar(op[col]) ;
col ^= 1 ;
per(i, a / b - 1, 1) putchar(op[col]) ;
} else {
per(i, a / b, 1) putchar(op[col]) ;
}
if (a / b) col ^= 1 ;
return ;
}
signed main() {
ans = iinf ;
scanf("%d%d", &n, &r) ;
rep(i, 0, r) {
cur = mst = 0 ;
if (gcd(i, r) != 1 || cur != n) continue ;
if (mst < ans) { ans = mst ; ansid = i ; }
}
if (ans == iinf) print("IMPOSSIBLE") ;
printf("%d\n", ans) ;
solve(ansid, r) ;
return 0 ;
}
加油ヾ(◍°∇°◍)ノ゙