zoukankan      html  css  js  c++  java
  • CodeForces 558C.Amr and Chemistry(多源BFS)

    题意:给定一个序列ai,你需要通过下面两个操作让序列中的所有数相等。
    1.选中某个数ai, ai = ai * 2
    2.选中某个数ai, ai = ai / 2(如3 / 2 = 1)
    求使全部数都相等的最小操作数。

    分析:这是道BFS,需要对每个数都BFS一下,搜索出这个数所能到达的每个数,累加到cnt[i],下标i表示这个数,(cnt[i])表示被不同的数到达的次数总和,如果这个次数为n,说明每个数都可以变换到这个数,因此可以更新答案。CF对memeset的卡时间非常严格,我们可以用队列存储pair<int, int>,这样就不需要开dist数组了。

    和这种题差不多,题目链接

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <queue>
    #include <algorithm>
    
    using namespace std;
    using PII = pair<int, int>;
    const int N = 200005;
    const int inf = 0x3f3f3f3f;
    int a[N];
    
    //到达每个数的总操作次数
    int num[N];
    
    //这个数被达到的次数
    int cnt[N];
    
    bool st[N];
    
    void bfs(int x)
    {
    	memset(st, 0, sizeof st);
    	queue<PII> q;
    	q.push({ x, 0 });
    	++cnt[x];
    	st[x] = true;
    
    	while (q.size())
    	{
    		auto t = q.front();
    		q.pop();
    		int x = t.first;
    		int y = t.second;
    		if ((x << 1) <= 1e5 && !st[x << 1])
    		{
    			st[x << 1] = true;
    			++cnt[x << 1];
    			q.push({ x << 1, y + 1 });
    			num[x << 1] += y + 1;
    		}
    
    		if ((x >> 1) >= 1 && !st[x >> 1])
    		{
    			st[x >> 1] = true;
    			++cnt[x >> 1];
    			q.push({ x >> 1, y + 1 });
    			num[x >> 1] += y + 1;
    		}
    
    	}
    }
    
    int main()
    {
    	int n;
    	cin >> n;
    
    	for (int i = 1; i <= n; ++i) cin >> a[i], bfs(a[i]);
    
    	int res = inf;
    	for (int i = 1; i <= N - 5; ++i)
    	{
    		if (cnt[i] == n)
    		{
    			res = min(res, num[i]);
    			//cout << i << endl;
    		}
    	}
    	printf("%d
    ", res);
    	return 0;
    }
    
  • 相关阅读:
    父类与子类之间的调用顺序
    ROW_NUMBER() OVER函数的基本用法用法
    String类
    代码块
    权限修饰符
    内部类
    final&static
    面向对象思想
    oracle存储过程常用技巧
    ORACLE EXECUTE IMMEDIATE 用法
  • 原文地址:https://www.cnblogs.com/pixel-Teee/p/13282127.html
Copyright © 2011-2022 走看看