UVA 6855 Banks 思维题

题目描述:

On Wall Street from Wonderland, we have n banks, with 10000 > n > 0. Each bank has exactly two neighbours, the left (L) and right (R) neighbour. The first bank’s left neighbour is the last bank,
while the last bank’s right neighbour is the first bank. Each bank i (n > i ≥ 0) has a capital ki with 32000 > ki > −32000. The entire capital of all banks put together is known to be positive. Whenever
some capital ki of bank i is negative, the Bank Fairy can do a magic move and turn the capital into a positive one. For instance, if ki = −7, after the magic move, ki = 7. Unfortunately, the magic move
has consequences for both neighbours of bank i. Each sees its capital reduced with the absolute value of the capital of bank i. For instance if bank L has capital kL = 5 and bank R has capital kR = 11, then after the magic move kL = −2 and kR = 4.
Which is the minimal number of magic moves which the Bank Fairy has to do in order to make the capital of all banks greater than or equal to 0?
Input
The input file contains several test cases, each of them as described below.
On the first line, we have the number n of banks. On the second line, we have the capitals ki(n > i ≥ 0) of all banks, in the order in which they are found on Wall Street from Wonderland. Each
capital is separated by a single white space from the next one, except for the final capital which is directly followed by the newline character.
Output
For each test case, the output contains a single line with the value of the minimal number of magic
moves.
Sample Input

4
1 -2 -1 3

Sample Output

9

题目分析:

有n个整数,其中他们的和大于0,有如下操作,将一个负数变成其相反数,同时其两侧的数(左侧和右侧)同时减去这个数的绝对值。问,经过多少次操作,这一系列的数全为非负数。(第一个数的左侧数是最后一个数,最后一个数的右侧数是第一个数)。

我们可以知道,每次操作所有数的和是没有变化的,因此我们只需要循环地从前向后找一遍负数,进行变化,记录变化次数就可以了。不需要找先对哪个数进行变化,都是一样的。

代码如下:

#include <iostream>
#include <cstdio>
using namespace std;

int a[10005];
int main()
{
    int n;
    while(scanf("%d",&n)!=-1)
    {
        for(int i=0; i<n; i++)
            scanf("%d",&a[i]);
        int flag=0,ans=0,pre,nex;
        while(flag==0)
        {
            for(int i=0; i<n; i++)
            {
                if(a[i]<0)
                {
                    pre=(i-1+n)%n;
                    nex=(i+1)%n;
                    a[pre]+=a[i];
                    a[nex]+=a[i];
                    a[i]=-a[i];
                    ans++;
                }
            }
            flag=1;
            for(int i=0; i<n; i++)
            {
                if(a[i]<0)
                {
                    flag=0;
                    break;
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值