cf839B Game of the rows

座位分配贪心算法
本文介绍了一种关于座位分配的贪心算法问题。通过将座位分为4人座和2人座,采用特定策略来分配不同组成员的座位,确保满足不同组成员不相邻的要求。最后通过比较剩余座位和需求来判断是否可行。

非常有趣的一道贪心题。考试期间我是毫无思路,然后今天看作者的题解,哇,真玄学。下面我大概就把作者的题解思路说一下,然后誊写一遍作者的代码


题意大概是这样的,一帮人选座位,要求不同组的不能坐在一起。每一行的座位构成都是这样的:
这里写图片描述
那么显然12 34 45 56 78是邻位。现在给你各组的人数,问能不能满足条件。
好,首先为了粉碎一些天真的想法,我们先举几个蛇皮走位:
1行,2个组,每组4个,方法是这样的:
这里写图片描述
又如,1行4个组,是2 2 2 1,方法:
这里写图片描述


那么作者本人是怎么想的呢?
首先我们将座椅分为两种,一种是4人座,一种是2人座。一共有n排,就先将n排分为n个4人座与2n个2人座。

好,那么假设某一组有k个人。我们优先让他们坐在4人座上,如果没有空余的4人座,就让他们去坐2人座。为什么这样排?因为4人座没有两人座灵活,如果某一组有3个人,那么分在一个4人座、2个2人座是等价的;而如果两个组人数分别为为2,2,分两个两人座是允许的,但没办法放四人座;如果两个组人数分别为1,1,1个4人座与2个2人座也是等价的。所以我们发现,4人座安排上没有两人座方便,所以我们优先四人座。

因此我们的第一步就是遍历让k-4,如果没有两人座就-2。当然,这个过程如果4人座和2人座都满了,那直接超载,别多想。而遍历的终止时机,则是k<=2.现在我们剩下的人只有两种情况:1个人成1组,2个人成1组。

对于两人组的处置,我们优先放2人座。因为如果放到4人座上,就会使得4人座只能放一个人。如果2人座满了,就将4人座拆成一个两人座和一个单人座。实在不行先将两个人拆成两个单人,这样,我们消灭了所有的2人,只剩下一堆的单人成组和一堆座。一个四人座可以充当两个单人座,所以最后的判断就是比较单人剩余数量与(2*4人座数量+2人座数量+单人座数量),比较一下就可以了。

总结一下这个结果是如何得出的。

  • 将每个组的人优先分到4人座上,不够的再分到两人座上,直到剩余1个或2个人
  • 将每个2人组优先分到2人座上,否则将4人座拆为1双1单,否则拆成两个单人
  • 比较最后剩余的可座的座位数与单人的剩余量。

那么代码就呼之欲出了:

#include <bits/stdc++.h>
using namespace std;
#define maxn 10003
int twose,fouse,onese;
int cou[4];
int main(){
    int n,k;
    cin>>n>>k;
    twose=n<<1,fouse=n;
    for(int i=0;i<k;++i){
        int p;cin>>p;
        while(p>=3){//步骤1
            if(fouse>0)
                p-=4,--fouse;
            else if(twose>0)
                p-=2,--twose;
            else{
                cout<<"NO"<<endl;
                return 0;
            }
        }
        if(p>0) cou[p]++;
    }
    while(cou[2]){//步骤2
        if(twose>0)
            --cou[2],--twose;
        else if(fouse>0)
            --cou[2],--fouse,++onese;
        else
            --cou[2],cou[1]+=2;
    }
    if(cou[1]<=onese+twose+2*fouse) cout<<"YES"<<endl;//步骤3
    else cout<<"NO"<<endl;
    return 0;
}

贪心好难啊qwq

#include <bits/stdc++.h> using namespace std; typedef long long ll; #define INF 0x7ffffff #define rep(i,s,t) for(register ll i = s;i <= t;++i) #define per(i,t,s) for(register ll i = t;i >= s;--i) const ll N = 25; struct node { ll x; ll y; ll rnk; bool operator < (const node& u) const { return rnk < u.rnk; } bool operator == (const node& u) const { return x == u.x && y == u.y && rnk == u.rnk; } }; ll n; ll m; ll ans = INF; ll dx[5] = {0,0,1,0,-1}; ll dy[5] = {0,1,0,-1,0}; char a[N][N] = {}; set <node> s; inline ll read() { ll x = 0; ll y = 1; char c = getchar(); while(c < '0' || c > '9') { if(c == '-') y = -y; c = getchar(); } while(c >= '0' && c <= '9') { x = (x << 3) + (x << 1) + (c ^ '0'); c = getchar(); } return x * y; } inline void write(ll x) { if(x < 0) { putchar('-'); write(-x); return; } if(x > 9) write(x / 10); putchar(x % 10 + '0'); } inline bool posfind(node tmp,set <node> cur) { for(register auto i : cur) if(i.x == tmp.x && i.y == tmp.y) return true; return false; } inline void bfs() { queue <pair<set <node>,ll> > q; q.push({s,0}); while(!q.empty()) { set <node> cur = q.front().first; ll stp = q.front().second; q.pop(); node head = *cur.begin(); if(a[head.x][head.y] == '@') { ans = stp; break; } ll cnt = 0; set <node> tmp; for(register auto i : cur) { cnt++; if(cnt == 1 || cnt == cur.size()) continue; tmp.insert({i.x,i.y,i.rnk + 1}); } rep(i,1,4) { ll nx = head.x + dx[i]; ll ny = head.y + dy[i]; node tmp1 = {nx,ny,1}; if(posfind(tmp1,tmp) || a[nx][ny] == '#' || nx < 1 || nx > n || ny < 1 || ny > m) continue; set <node> tmp2 = tmp; tmp2.insert(tmp1); q.push({tmp2,stp + 1}); } } } int main() { cin >> n >> m; rep(i,1,n) { rep(j,1,m) { cin >> a[i][j]; if(a[i][j] >= '0' && a[i][j] <= '9') s.insert({i,j,(ll)(a[i][j] - '0')}); } } bfs(); if(ans == INF) cout << -1; else cout << ans; return 0; }请针对以下问题优化上述代码的时间空间复杂度,极度精确保留源代码风格# CF225D Snake ## 题目描述 Let us remind you the rules of a very popular game called "Snake" (or sometimes "Boa", "Python" or "Worm"). The game field is represented by an $ n×m $ rectangular table. Some squares of the field are considered impassable (walls), all other squares of the fields are passable. You control a snake, the snake consists of segments. Each segment takes up exactly one passable square of the field, but any passable square contains at most one segment. All segments are indexed by integers from $ 1 $ to $ k $ , where $ k $ is the snake's length. The $ 1 $ -th segment is the head and the $ k $ -th segment is the tail. For any $ i $ ( $ 1<=i<k $ ), segments with indexes $ i $ and $ i+1 $ are located in the adjacent squares of the field, that is, these squares share a common side. One of the passable field squares contains an apple. The snake's aim is to reach the apple and eat it (that is, to position its head in the square with the apple). The snake moves throughout the game. During one move the snake can move its head to an adjacent field square. All other segments follow the head. That is, each segment number $ i $ $ (1<i<=k) $ moves to the square that has just had segment number $ i-1 $ . Consider that all segments including the head move simultaneously (see the second test sample). If the snake's head moves to an unpassable square or to the square, occupied by its other segment, the snake dies. That's why we will consider such moves unvalid. Your task is to determine the minimum number of valid moves that the snake needs to reach the apple. ## 输入格式 The first line contains two space-separated integers $ n $ and $ m $ ( $ 1<=n,m<=15 $ ) — the number of rows and columns of the game field. Next $ n $ lines describe the game field. Each of these lines contains $ m $ characters. Character "\#" represents a wall, "." is a passable square, "@" is an apple. The snake's first segment is represented by character "1", the second one segment — by character "2" and so on. The game field description doesn't contain any characters besides "\#', ".", "@" and digits (except 0). It is guaranteed that the described field is correct. It is guaranteed that the described field contains exactly one apple and exactly one snake, the snake's length is at least 3 and at most 9. ## 输出格式 Print a single integer to the output — the minimum number of moves needed to reach the apple. If the snake can't reach the apple, print -1. ## 输入输出样例 #1 ### 输入 #1 ``` 4 5 ##... ..1#@ 432#. ...#. ``` ### 输出 #1 ``` 4 ``` ## 输入输出样例 #2 ### 输入 #2 ``` 4 4 #78# .612 .543 ..@. ``` ### 输出 #2 ``` 6 ``` ## 输入输出样例 #3 ### 输入 #3 ``` 3 2 3@ 2# 1# ``` ### 输出 #3 ``` -1 ```
最新发布
07-18
System Identification报错“the same number of rows”通常是因为输入数据的行数不一致导致的。在进行系统辨识时,输入数据和输出数据必须具有相同的行数,即时间步长必须一致。如果行数不一致,系统辨识工具无法正确匹配输入和输出数据,从而导致报错。 以下是一些可能的原因和解决方法: 1. **数据长度不一致**: - 确保输入数据和输出数据具有相同的时间步长。可以使用MATLAB中的`size`函数来检查数据的长度。 2. **数据预处理问题**: - 在进行系统辨识前,确保对输入和输出数据进行了相同的预处理操作,例如去均值、归一化等。 3. **数据导入错误**: - 检查数据导入过程,确保没有意外地删除或添加了数据行。 4. **时间向量不一致**: - 确保时间向量与数据的长度一致。如果时间向量不正确,可能会导致数据对不齐。 以下是一个简单的示例代码,展示了如何检查输入和输出数据的长度: ```matlab % 假设 input_data 和 output_data 是你的输入和输出数据 input_length = size(input_data, 1); output_length = size(output_data, 1); if input_length ~= output_length error('Input and output data must have the same number of rows. Current lengths are %d and %d.', input_length, output_length); end % 进行系统辨识 % sys = tfest(data, np, nz); ``` 通过这种方式,可以确保输入和输出数据的长度一致,从而避免“the same number of rows”错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值