• 【题解】【CodeForces653F】Ants on a Circle


    题目链接

    点击打开链接

    题目解法

    先观察蚂蚁运动的方式(observation),可以发现下面几件事情:

    1. 蚂蚁的顺序不变。
    2. 蚂蚁最终所在位置就是“两只蚂蚁相遇后穿透”的最终位置。所以可以得出蚂蚁最终在哪些位置。

    所以现在可以知道蚂蚁的最终位置与蚂蚁的顺序。但是满足最终位置和顺序的蚂蚁位置方案数有 (n) 种(因为是环,所以可以转 (n) 下)。所以需要知道最终结果对应的是哪一种。

    现在定义一个环对应的排列是这样的:从 0 开始顺时针向后每一个蚂蚁的编号。那么只要一只蚂蚁从位置 m-1 走到了位置 0 ,那么排列就会向右轮换一下。如果一只蚂蚁从位置 0 走到了位置 m-1 ,那么排列会向左轮换一下。所以只需要求出每只蚂蚁顺着/倒着穿过了 0 多少次,这个次数其实与“蚂蚁相遇后穿过”顺着、倒着穿过 0 的次数等价。这样就可以求出到底是哪一个轮换了。那就做完了。

    总结

    • 整体考虑轮换(宏观思考),而不要想着求一个蚂蚁最终的位置(虽然可以做,但是特别麻烦)(微观思考)。

    代码

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 3e5 + 5;
    ll n, m, pp[N], ans[N];
    ll t;
    struct ANT {
    	ll pos, dir, id;
    	bool operator < (const ANT &d) const { return pos < d.pos; }
    } ant[N];
    ll Get(ll x) {
    	if (ant[x].dir == -1) {
    //		if (t >= ant[x].pos && ant[x].pos != 0)
    //			return ((t - ant[x].pos) / m + 1);
    //		else if (ant[x].pos == 0)
    //			return (t - ant[x].pos) / m;
    //		else return 0; 
    		return (t - ant[x].pos + m - 1) / m;
    	} else {
    		if (t >= m - ant[x].pos)
    			return -((t - (m - ant[x].pos)) / m + 1);
    		else return 0;
    //		return - (t + ant[x].pos) / m;
    	}
    }
    int main() {
    	scanf("%lld%lld%lld", &n, &m, &t);
    	for (ll i = 0; i < n; ++i) {
    		scanf("%lld", &ant[i].pos);
    		--ant[i].pos;
    		char dd = getchar();
    		while (dd == ' ') dd = getchar();
    		ant[i].dir = (dd == 'L') ? -1 : 1;
    		ant[i].id = i;
    	}
    	sort(ant, ant + n);
    	for (ll i = 0; i < n; ++i)
    		pp[i] = ((t * ant[i].dir + ant[i].pos) % m + m) % m;
    	sort(pp, pp + n);
    	ll bg = 0;
    	for (ll i = 0; i < n; ++i)
    		bg = (Get(i) + bg) % n;
    	bg = (bg + n) % n;
    	for (ll i = bg, j = 0; j < n; ++j, i = (i + 1) % n)
    		ans[ant[i].id] = pp[j];
    	for (ll i = 0; i < n; ++i)
    		printf("%lld ", ans[i] + 1);
    	printf("
    ");
    	return 0;
    }
    
  • 相关阅读:
    rem是如何实现自适应中的?
    meta基础知识
    JqueryMobile动态生成listView并实现刷新的两种方法
    javascript中for/in循环及使用技巧
    JavaScript中this详解
    使用css实现全兼容tooltip提示框
    如何使用CSS3画出一个叮当猫
    jQuery实现的Div窗口震动效果实例
    jQuery实现动态添加和删除一个div
    js对文章内容进行分页示例代码
  • 原文地址:https://www.cnblogs.com/YouthRhythms/p/13326862.html
Copyright © 2020-2023  润新知