Codeforces Round #647 (Div. 2)

A. Johnny and Ancient Computer

模拟判断。

AC代码:

int main()
{
	int t;
	sd(t);
	while (t--)
	{
		ll n, m;
		sldd(n, m);
		if (n == m)
		{
			puts("0");
			continue;
		}
		ll ans = 0;
		if (n < m)
			swap(n, m);
		ll res = n / m;
		if (n % m != 0 || res & 1)
		{
			puts("-1");
			continue;
		}
		while (res >= 8)
		{
			if (res % 8 != 0)
				break;
			ans++;
			res /= 8;
		}
		while (res >= 4)
		{
			if (res % 4 != 0)
				break;
			ans++;
			res /= 4;
		}
		while (res >= 2)
		{
			if (res % 2 != 0)
				break;
			ans++;
			res /= 2;
		}
		if (res == 1)
			pld(ans);
		else
			puts("-1");
	}
	return 0;
}

B. Johnny and His Hobbies

k k k 最大也只有 1023 1023 1023 ,所以暴力枚举比较即可。

AC代码:

const int N = 2e5 + 50;
int n, m;
int a[N], b[N];
int main()
{
	int t;
	sd(t);
	while (t--)
	{
		sd(n);
		int maxn = 0;
		rep(i, 1, n)
			sd(a[i]);
		sort(a + 1, a + 1 + n);
		int ans = 10000;
		bool flag = 1;
		rep(i, 1, 1024)
		{
			flag = 1;
			rep(j, 1, n)
				b[j] = a[j] ^ i;
			sort(b + 1, b + 1 + n);
			rep(j, 1, n)
			{
				if (b[j] != a[j])
				{
					flag = 0;
					break;
				}
			}
			if (flag)
			{
				ans = i;
				break;
			}
		}
		if (ans <= 1024)
			pd(ans);
		else
			puts("-1");
	}
	return 0;
}

C. Johnny and Another Rating Drop

多写几项就能发现规律。

00000
00001  1
00010  2
00011  1
00100  3
00101  1
00110  2
00111  1
01000  4
01001  1
01010  2
01011  1
01100  3
01101  1
01110  2
01111  1
10000  5
10001  1
10010  2
10011  1
10100  3
10101  1
10110  2
10111  1
11000  4

可以看出每当第 n n n 位进 1 1 1 后对贡献就是多了 2 n 2^n 2n

AC代码:

int main()
{
	int t;
	sd(t);
	while (t--)
	{
		sld(n);
		ll ans = 0, res = n, i = 1;
		while (res)
		{
			ans += n / i;
			i *= 2;
			res >>= 1;
		}
		pld(ans);
	}
	return 0;
}

D. Johnny and Contribution

题意很难理解,大概就是每个博客都能选到每个博客想要写的题目,让你给出一个写的顺序,那肯定是贪心的先把主题为 1 1 1 的都给写了,然后每次判断和当前正在写的这个节点相连的节点有没有满足邻居个数符合条件可以写的,如果符合就把这个也给写了,然后把他的邻居个数加 1 1 1 ,统计每个节点的邻居个数判断。

AC代码:

const int N = 5e5 + 50;
int cnt[N], n, m;
vector<int> v[N], ans, rec[N];
int main()
{
	sdd(n, m);
	rep(i, 1, m)
	{
		int x, y;
		sdd(x, y);
		v[x].pb(y);
		v[y].pb(x);
	}
	rep(i, 1, n)
	{
		int t;
		sd(t);
		rec[t].pb(i);//第i个节点邻居个数为t
		cnt[i] = 1;//第i个节点的邻居个数
	}
	rep(i, 1, n)
	{
		for (auto u : rec[i])//邻居个数为i的全部节点
		{
			if (cnt[u] != i)
			{
				puts("-1");
				return 0;
			}
			for (auto x : v[u])
				if (cnt[x] == i)
					cnt[x]++;
			ans.pb(u);
		}
	}
	for (auto it : ans)
		printf("%d ", it);
	return 0;
}

你可能感兴趣的:(CodeForces)