zoukankan      html  css  js  c++  java
  • Codeforces 1355 F-Robots on a Grid (倍增)

    题目:
    • n*m的黑白网格,给出每个格子的颜色以及下一步移动的方向。当给一个位置放一个机器人,它会按照每个位置的信号移动,可以放多个机器人,但要求相同时刻一个位置不能出现两个机器人。求最多可以放多少个机器人,机器人数量相同时最多有多少个机器人放在黑格子上。

    • 参考题解。观察样例发现,这些控制指令可以使整个网格看作一个有向图,某些指令会构成一个环,到环上各点的只能是一条简单通路。因为有环所以nm步后机器人一定进入环中,所以我们可以用倍增的方法求每个点到(2^{i})的位置。然后就可以得到每个位置机器人在nm步后的位置。这些位置的个数就是机器人总数,如果是从黑格子出发到达的就算在黑格子机器人数量中。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<map>
    #include<queue>
    #include<vector>
    #include<string>
    #include<fstream>
    using namespace std;
    #define rep(i,a,n) for(int i = a; i <= n; ++ i);
    #define per(i,a,n) for(int i = n; i >= a; -- i);
    typedef long long ll;
    const int N = 1e6 + 105;
    const int mod = 998244353;
    const double Pi = acos(- 1.0);
    const int INF = 0x3f3f3f3f;
    const int G = 3, Gi = 332748118;
    ll qpow(ll a, ll b) { ll res = 1; while(b){ if(b) res = (res * a) % mod; a = (a * a) % mod; b >>= 1;} return res; }
    ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
    //
    
    int T, n, m;
    int f[N][50];
    int col[N], B[N], W[N];
    int res1, res2;
    char s[N];
    
    int main()
    {
        scanf("%d",&T);
        while(T --){
            res1 = res2 = 0;
            scanf("%d%d",&n,&m);
            for(int i = 1; i <= n; ++ i){ 
                scanf("%s",s + 1);
                for(int j = 1; j <= m; ++ j){
                    int v = (i - 1) * m + j;
                    col[v] = (s[j] == '0');
                }
            }
            
            for(int i = 1; i <= n; ++ i){
                scanf("%s",s + 1);
                for(int j  = 1; j <= m; ++ j){
                    int v = (i - 1) * m + j;
                    if(s[j] == 'U') f[v][0] = v - m;
                    else if(s[j] == 'D') f[v][0] = v + m;
                    else if(s[j] == 'R') f[v][0] = v + 1;
                    else if(s[j] == 'L') f[v][0] = v - 1;
                }
            }
            
            for(int j = 1; j <= 20; ++ j)
                for(int i = 1; i <= n * m; ++ i)
                    f[i][j] = f[f[i][j - 1]][j - 1];
    
            for(int i = 1; i <= n * m; ++ i){
                int to = i;
                for(int j = 20; j >= 0; -- j){
                    if((1 << j) & (n * m)) to = f[to][j];
                }
                if(col[i]) B[to] = 1;
                else W[to] = 1;
            }
            
           for(int i = 1; i <= n * m; ++ i){
               if(B[i]) res1 ++, res2 ++, B[i] = W[i] = 0;
               else if(W[i]) res1 ++, W[i] = B[i] = 0;
           }
           printf("%d %d
    ",res1,res2);
        }
        return 0;
    }
    
    
  • 相关阅读:
    TCP/IP和HTTP的举例理解
    c#中栈和堆的理解
    c#设计模式之单例模式
    JSON.stringify实例应用—将对象转换成JSON类型进行AJAX异步传值
    JSON.stringify初识
    c# 过滤字符串中的重复字符
    C#中jQuery Ajax实例(二)
    C#中jQuery Ajax实例(一)
    jQuery动态对表格Table进行添加或删除行以及修改列值操作
    asp.net中控件的Attributes用法
  • 原文地址:https://www.cnblogs.com/A-sc/p/12852812.html
Copyright © 2011-2022 走看看