【51Nod1293】球与切换器

40 篇文章 0 订阅

有N行M列的正方形盒子。每个盒子有三种状态0, -1, +1。球从盒子上边或左边进入盒子,从下边或右边离开盒子。规则:
如果盒子的模式是-1,则进入它的球从下面出去。(方向变为向下)
如果盒子的模式是+1,则进入它的球从右面出去。 (反向变为向右)
如果盒子的模式是0, 则进入它的球方向不变。从上面进入的,从下面出去,从左面进入的,从右面出去。

这里写图片描述

球离开一个盒子,这个盒子的模式切换为相反数。已知,每个盒子的状态,扔k个球,它们都从左上角那个盒子的上面进入(方向向下),问最终有几个球从右下角的盒子的下边出去。
(可以理解维球一个一个放,等待的时间足够长,不会有两个球同时进入一个盒子的情形)本题由Javaman翻译。
Input
第1行:包括3个数M, N, K中间用空格分隔,M,N 为盒子的宽度和高度,K为球的数量(1 <= M, N <= 1000, 1 <= K <= 10^18)。
第2 - N + 1行:每行M个数(-1, 0 或 1),表示对应的模式。
Output
输出1个数,对应最终有有多少个球从右下角的盒子的下边出去。
Input示例
3 2 4
-1 0 -1
1 0 0
Output示例
1

题解
如果一个点为1,则可以认为经过他的球(sum个),有(sum+1)/2个球往右,sum/2个球往下,DP即可。

代码

#include<bits/stdc++.h>
#define inf 0x7fffffff
#define N 20005
#define M 400005
#define ll long long
using namespace std;
inline ll read()
{
    ll x=0LL,f=1LL;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
ll dp[1005][1005][2],k;
int n,m;
int main()
{
    m=read();n=read();k=read();
    dp[1][1][0]=k;
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
        {
            int t=read();
            ll sum=dp[i][j][1]+dp[i][j][0];
            if (t==0) dp[i][j+1][1]+=dp[i][j][1],dp[i+1][j][0]+=dp[i][j][0];
            if (t==1) dp[i][j+1][1]+=(sum+1)/2,dp[i+1][j][0]+=sum/2;
            if (t==-1) dp[i][j+1][1]+=sum/2,dp[i+1][j][0]+=(sum+1)/2;
        }
    printf("%lld",dp[n+1][m][0]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值