EOJ 2015.自修室(排序 神奇的Rocker)

2015. 自修室

一直不去自修室的 Rocker 最近迫于学习压力决定每天都要去自修,鉴于自修室多多,何必与人争挤,所以 Rocker 要坐在左右一个座位都没人,如果不是第一排,那么他的前面一个座位也没有人的位置上,当然 Rocker 也可以坐在墙边但前面或左边或右边有座位的话要没有人才可以。

Rocker 眼力异常好,只要在门口瞟一眼就可以知道哪个位置上有人哪个没有人,但 Rocker 大脑毕竟不像电脑可以迅速计算出这间教室有没有符合他要求的位置,所以请你写一个程序帮助他。

输入格式

输入有多个case
每个case第一行有一个数n表示自修室的总间数,接下来描述n(小于100)个自修室的座位情况,
接下来按照 Rocker 对于每间自修室,第一行有四个整数ID,Dis,R,C,分别是教室的门号,教室距离 Rocker 寝室的距离,座位的行数以及列数。
接下来是一个R*C的 0-1 矩阵,0 表示该座位没有人,1 表示有人。(每间教室 ID和Dis,互异),Rocker 按照距离远近依次找教室自修,去距离寝室最近的一间满足他条件的教室自修。

输出格式

每个case输出一行,如果有Rocker 可以自修的教室 ,输出教室的ID;若无教室符合条件,输出 “Bad Luck,Rocker!”

分析

  1. 和life game的思想类似,对座位矩阵中每个元素进行判断。
  2. 技巧:给矩阵第一行最后一行第一列最后一列都加上一排空座位,这样判断的时候就可以不用分情况讨论该座位是不是有前后左右的座位。
  3. 先按照距离从小到大排序,然后从第一个教室开始筛选,如果符合情况就直接输出结束;如果直到最后一个教室都没有符合情况的,就是没有可以自修的教室

AC代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
//from 0vv
struct room{
    long long id;
    int dist;
    int row;
    int col;
    char seat[22][22];
};
int cmp(const void*a,const void*b)
{
    room*p1=(room*)a;
    room*p2=(room*)b;
    return p1->dist>p2->dist;
}
int isvalid(char m[22][22],int r,int c)
{
    char tmp[r+2][c+2];
    for(int i=0;i<=r+1;i++)
    {
        for(int j=0;j<=c+1;j++)
        {
            tmp[i][j]='0';
        }
    }
    for(int i=1;i<r+1;i++)
    {
        for(int j=1;j<c+1;j++)
        {
            if(m[i-1][j-1]=='1')
                tmp[i][j]='1';
        }
    }
    for(int i=1;i<r+1;i++)
    {
        for(int j=1;j<c+1;j++)
        {
            int cnt=0;
            if(tmp[i-1][j]=='0')
                cnt++;
            if(tmp[i][j-1]=='0')
                cnt++;
            if(tmp[i][j+1]=='0')
                cnt++;
            if(cnt==3&&tmp[i][j]=='0')
            {
                 //cout<<"i:"<<i<<" j:"<<j<<endl;
                 return 1;
            }
        }
    }
    return 0;
}
int main()
{
    int n;
    while(cin>>n)
    {
        room myroom[n];
        for(int i=0;i<n;i++)
        {
            scanf("%lld %d %d %d",&myroom[i].id,&myroom[i].dist,&myroom[i].row,&myroom[i].col);
            for(int j=0;j<myroom[i].row;j++)
            {
                scanf("%s",&myroom[i].seat[j]);
            }
        }
        qsort(myroom,n,sizeof(myroom[0]),cmp);
        int sign=0;
        for(int i=0;i<n;i++)
        {
            if(isvalid(myroom[i].seat,myroom[i].row,myroom[i].col))
            {
                cout<<myroom[i].id<<endl;
                sign=1;
                break;
            }
        }
        if(sign==0)
            cout<<"Bad Luck,Rocker!"<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值