Google APAC Round D题解

Problem A. Dynamic Grid
最基础的搜索,我用DFS做的,标记棋盘上每一个位置初始化为未搜索,遍历整个棋盘,如果遇到1且以前从没搜索到的话就从该点开始不停搜索,直到搜完,复杂度O(m*n)

代码

int m, n;
int q;
char b[110][110];
bool flag[110][110];
bool valid(int x ,int y)
{
    if(x < 0 || x >= m)
        return false;
    if(y < 0 || y >= n)
        return false;
    if(flag[x][y] == 1)
        return false;
    if(b[x][y] != '1')
        return false;
    return true;
}
void DFS(int x ,int y)
{
    flag[x][y] = 1;
    if(valid(x - 1, y))
        DFS(x - 1, y);
    if(valid(x + 1, y))
        DFS(x + 1, y);
    if(valid(x, y - 1))
        DFS(x, y -1);
    if(valid(x, y + 1))
        DFS(x, y + 1);
}
int solve()
{
    ZERO(flag);
    int count = 0;
    FOR(i,0,m)
    FOR(j,0,n)
    {
        if(b[i][j] == '1' && flag[i][j] == false)
        {
            DFS(i,j);
            count++;
        }
    }
    return count;
}
int main(){
    int Tcase;
    cin >> Tcase;

    FOR(hh,0,Tcase)
    {
        cin >> m >> n;
        FOR(i,0,m)
        FOR(j,0,n)
        cin >> b[i][j];
        cin >> q;
        cout << "Case #" << hh + 1 << ":" << endl;
        char ops;
        FOR(i,0,q)
        {
            cin >> ops;
            if(ops == 'Q')
                cout << solve() << endl;
            else
            {
                int x ,y;
                char val;
                cin >> x >> y >> val;
                b[x][y] = val;
            }
        }
    }

    return 0;
}

Problem B. gBalloon
很有意思的题目,首先考虑不可能的情况:
1.如果风向和距离的乘积为正数或者0(距离不为0),那么一定需要移动这个气球(称之为坏球),记下所需要的最小的消耗,如果所有坏球所需最小消耗的和大于q,那么不可能。
2.考虑如果需要移动气球,那么肯定是在时刻0的时候移动,我们用set维护一个3-element entry记录(当前气球标号,该球消耗的能量,到达0位置所需要的时间),并按最后一项的值从大向小排序。初始化时所有好球消耗的能量为0,时间根据dis/v向上取整。所有坏球计算所需最小的消耗和时间。每次从set中拿出第一位的项(时间最长),因为是它限制了最后到达的时间,给他能量看能否快过第二项,如果在当前能量+之前消耗的 可以保证他快过第二项,那么更新该项并且重新插入,同时更新剩余的能量。如果不能的话则循环结束,将所有的剩余能量尝试更新最开始的项,返回该项所需的时间。
因为每次消耗的q会最少增加1,所以总得复杂度是O(q * m * logn)

#define FOR(a, b, n) for(int (a) = (b); (a) < (n); ++(a))
#defin
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值