2024.09.08小红书

1. 机器人走网格

小红书的冒险家们!今天,我们要进入一个充满挑战的高科技迷言。这是一张由小红书科技部最新研发的网格地图,每个格子都营着秘密一它们内置了自动滑行带!这些
滑行带会让所有进入它们的机器人自动翻一个特定方向滑行。
网格地图每个格子都藏着秘密一它们内置了自动滑行带!这些滑行带会让所有进入它们的机器人自动朝一个特定方向滑行。
具体来说,一张n*m的网格地图,左上角为(1,1),右下角为(n,m),每个格子有一个滑行带,前进方向为L,R,U,D,分别表示左右上下四个方向前进。
机器人走出地图后就会毁坏,一个格子可以容纳多个机器人。
第0时刻,每个位置都有一个机器人,问:第10^8时刻,地图上还剩下多少个机器人?

有循环的会进行保留
int main() {
    int n,m;
    cin>>n>>m;
    int dir[4][2] = {{0,-1},{0,1},{-1,0},{1,0}};
    map<char,int> mp = {{'L',0},{'R',1},{'U',2},{'D',3}};
    vector<vector<int>> grid(n,vector<int>(m));
    vector<vector<int>> flag(n,vector<int>(m));//0表示还没有遍历过,1是循环,-1不是
    char c;

    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){ 
            cin>>c;
            grid[i][j] = mp[c];
        }
    }
    function<bool(int,int,int)> dfs = [&](int x,int y,int id)->bool{
        if(flag[x][y]>0) return true;
        if(flag[x][y]==-1) return false;
        int nx = x+dir[grid[x][y]][0];
        int ny = y+dir[grid[x][y]][1];
        if(nx<0||ny<0||nx==n||ny==m) return false;
        //边界条件
        flag[x][y] = id;
        if(flag[nx][ny]==id)
            return true;
        if(dfs(nx,ny,id))
            return true;
        flag[x][y] = -1;
        return false;
    };
    int res = 0;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(dfs(i,j,i*m+j+1)) res++;
        }
    }
    cout<<res<<endl;
    return 0;
}

2. 小苯到的区间和之和

小苯有一个长度为n的数组a,他定义了一个函数
\(f:f(l, r)=\sum_{k=l}^{r} a_{k}\)
即f(l,r)表示数组a在[l,r]这一段区间的区间和。现在小苯有一个重新任意排列数组a的机会,他想要最小化\(\sum_{r=l}^{n}\) f(l, r) 即最小化所有区间对应f的值之和,请你帮他算算最小的这个值吧。

贡献法的思维题
int main(int argc, char *argv[]) {
    vector<int> nums;
    int num;
    while(cin>>num){
        nums.push_back(num);
        if(cin.get()=='\n') break;
    }
    int n = nums.size();
    sort(nums.begin(),nums.end());
    vector<int> cnt(n);
    for(int i=0;i<n;i++)
        cnt[i] = (i+1)*(n-i-1);
    sort(cnt.begin(),cnt.end(),greater<int>());
    int res = 0;
    for(int i=0;i<n;i++)
        res+=nums[i]*cnt[i];
    cout<<res;
    return 0;
}

3. 小红的笔记精选

定义f(x)为×在二进制表示下的1的个数,例如f(7)=3,f(8)=1,f(9)=2.定义g(x)为第一个比x大的数字y,使得f(x)=f(y),
例如g(1)=2,g(2)=4,g(3)=5.小红书首页有n篇笔记,第i篇笔记的点赞数量为ai,我们希望从中挑选出一些笔记,构造一个长度为m的精选队列b1,b2,...,bm·在这里,
精选队列满足:对于所有的j∈[2,m],都有b_{j}=g(b_{j-1}) 。当然,精选队列越长越好,请你最大化其长度m,并输出之。

排序+动态规划+位运算思维题

ll anext(ll a){//找a的下一个更大满足条件值
    if (a == 0)
        return 0;
    ll base = 1;
    while ((base & a) == 0)  base <<= 1;
    while ((base & a) == base)  base <<= 1;
    
    a += base >> 1;
    ll b = a % base;
    a -= b;
    while (b > 0 && b % 2 == 0)
        b >>= 1;
    return a + b;
}


bool cmp(ll a, ll b) //按1的位数排序,相当于拆分掉不同1位数的数组
{
    if (__builtin_popcountll(a) != __builtin_popcountll(b))
        return __builtin_popcountll(a) < __builtin_popcountll(b);
    return a < b;
}

int main(int argc, char *argv[]) {
    int n;
    cin >> n;
    vector<ll> a(n);
    for (int i = 0; i < n; i++)
        cin >> a[i];
    sort(a.begin(), a.end(), cmp);
    ll ans = 1, cnt = 1;
    for (int i = 1; i < n; i++){
        if (a[i] == anext(a[i - 1]))  cnt++;
        else if (a[i] == a[i - 1])   continue;
        else{
            ans = max(ans, cnt);
            cnt = 1;
        }
    }
    ans = max(ans, cnt);
    cout<< ans << endl;
    return 0;
}

posted @ 2024-09-12 19:09  失控D大白兔  阅读(48)  评论(0编辑  收藏  举报