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 ;
}
posted @ 2019-07-20 15:01  harryhqg  阅读(252)  评论(0编辑  收藏  举报