牛客练习赛19-C-托米航空公司

链接: https://www.nowcoder.com/acm/contest/111/C
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

托米老师靠才华与颜值发家致富后,开了一家航空公司,公司的口号是“您想飞,我们便做您的翅膀~让您每次飞行都有独特的体验!”
但是现在有一个小小的问题需要解决,托米家的飞机每排有M个座位,有N排座位。因此座椅形成了M × N的网格(忽略过道),公司为每次航班都出售K张票。
为了满足口号中的“翅膀”部分,座位必须遵守以下规则:座位被占用时,座位正前方和座位后方的座位以及当前座位左边和右边必须是空的(大概是因为这个飞机会很大吧,boss就是这么任性哼)。
然后为了满足口号中的“独特体验”部分。公司则是对每一趟航班飞机的座位采取不同的安排,如果这一趟的某个座位是占用的,而另一趟的座位是空的,则这两趟飞机座位安排是不同的。
给你三个数字M,N和K。
现在需要从这些座位中选出k个合法的座位。由于这个数字可能非常大,我们只求它对420047取模的结果。

输入描述:

输入的第一行包含一个整数T,表示指定测试用例的数量。
每个测试用例前面都有一个空白行。
每个测试用例由包含三个整数M,N和K的一行组成。

输出描述:

对于每个测试用例输出一行,表示答案对420047取模的结果。


#include <bits/stdc++.h>

#define ll long long
using namespace std;
int a[85][85];
int dir[5][2]={-1,0, 1,0, 0,-1, 0,1, 0,0};//表示前后左右四个方向,多一个0,0是为了标记自身
int n,m;
int mod=420047;
int dfs(int k,int x)//k表示还要选多少个座位,x是已经遍历过多少座位 
{
if(k==0)
return 1;
int res=0;
for(int i=1;i<=n;i++)
   for(int j=1;j<=m;j++)
      {
       if(i*m+j<x)//i*m+j是当前座位序号,排数乘m加上第几列,最大序号是n*m
       continue;//由于后面的遍历序号一定变大,小就跳过
       if(a[i][j]==0)
       {
        for(int k=0;k<5;k++)
         a[i+dir[k][0]][j+dir[k][1]]++;//标记附近点和自身
         res+=dfs(k-1,i*m+j);
         res%=mod;
         for(int k=0;k<5;k++)
         a[i+dir[k][0]][j+dir[k][1]]--;//解除标记
 }
  }
return res;
}
int main()
{
int t;
memset(a,0,sizeof(a));
scanf("%d",&t);
while(t--)
{
int k;
scanf("%d %d %d",&n,&m,&k);
int ans=dfs(k,0);
printf("%d\n",ans);
}
return 0;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wym_king

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值