• 【luogu AT5160】Numbers on a Circle(贪心)(堆)


    Numbers on a Circle

    题目链接:luogu AT5160

    题目大意

    给你一个长度为 n 的环,你每次操作可以把一个位置加上它两边的值。
    然后给你初始状态和目标状态,问你至少要多少次操作才能实现,或者输出无法实现。

    思路

    考虑反过来,变成你每次会减去两边的值。
    那这个有什么用呢,你会发现每次只会有一些点可以做。
    (它一定要大于它两边的和)

    而且它们之间一定有间隔,也就是说它们之间谁先做无关。
    那我们就可以直接暴力用堆枚举它们,然后直接减。

    那你一次一次减当然是不可以的,所以我们要直接减到不能减。
    (或者减到目标,但如果减不到目标而且直接减会比目标小就无解)

    最后判一下是否全部都减好了就可行了。

    代码

    #include<queue>
    #include<cstdio>
    #define ll long long
    
    using namespace std;
    
    int n, a[200001], b[200001];
    priority_queue <pair<int, int> > q;
    bool ok[200001];
    ll ans;
    
    bool up(int now) {
    	if (ok[now]) return 0;
    	return b[now] > b[(now + 1) % n] + b[(now - 1 + n) % n];
    }
    
    int main() {
    	scanf("%d", &n);
    	for (int i = 0; i < n; i++)
    		scanf("%d", &a[i]);
    	for (int i = 0; i < n; i++)
    		scanf("%d", &b[i]);
    	
    	for (int i = 0; i < n; i++)
    		if (up(i)) q.push(make_pair(b[i], i));
    	
    	while (!q.empty()) {
    		int now = q.top().second;
    		q.pop();
    		
    		int to = b[now] % (b[(now + 1) % n] + b[(now - 1 + n) % n]);
    		if (to > a[now]) {
    			ans += b[now] / (b[(now + 1) % n] + b[(now - 1 + n) % n]); b[now] = to;
    			if (up((now + 1) % n)) q.push(make_pair(b[(now + 1) % n], (now + 1) % n));
    			if (up((now - 1 + n) % n)) q.push(make_pair(b[(now - 1 + n) % n], (now - 1 + n) % n));
    		}
    		else {
    			if ((b[now] - a[now]) % (b[(now + 1) % n] + b[(now - 1 + n) % n])) {
    				printf("-1"); return 0;
    			}
    			ans += (b[now] - a[now]) / (b[(now + 1) % n] + b[(now - 1 + n) % n]);
    			b[now] = a[now];
    			if (up((now + 1) % n)) q.push(make_pair(b[(now + 1) % n], (now + 1) % n));
    			if (up((now - 1 + n) % n)) q.push(make_pair(b[(now - 1 + n) % n], (now - 1 + n) % n));
    			ok[now] = 1;
    		}
    	}
    	
    	for (int i = 0; i < n; i++)
    		if (a[i] != b[i]) {
    			printf("-1"); return 0;
    		} 
    	
    	printf("%lld", ans);
    	
    	return 0;
    }
    
  • 相关阅读:
    [CF] Final Exam Arrangement
    [原创]9宫格填数字
    第二次结对编程作业
    第11组 团队展示
    第一次结对编程作业
    第一次个人编程作业
    第一次博客作业
    第二次结对编程作业
    第10组 团队展示
    第一次个人编程作业
  • 原文地址:https://www.cnblogs.com/Sakura-TJH/p/luogu_AT5160.html
Copyright © 2020-2023  润新知