UVA10726 Coco Monkey【暴力+模拟】

This is the story of a time long ago. There were these sailors stranded on a beautiful island full off coconut trees. And what do our sailors do with the coconut trees? They collect all the coconuts and divide those among themselves and the monkeys that they brought with them!

  History tells us that there were S sailors on the island, and they collected C coconuts in total. At nightfall they decided to leave the coconuts in a secret place and divide it equally in the morning. But as the night grew darker, the sailors began to get impatient. At midnight, one of the sailors got up. He dug up the coconuts and saw that after dividing the coconuts equally into S baskets, there are exactly M coconuts left. These, as you must have guessed, goes to the M monkeys that they have brought with them. Now, our greedy sailor took one of those baskets for himself and left the remaining S − 1 ones for his commodores. History repeats. So we have another sailor succumbing to the temptation of juicy coconuts. He again, divided the remaining coconuts equally in S baskets only to find M coconuts extra. One basket for himself, M coconuts for the M monkeys and the remaining S − 1 baskets for his fellows – that’s how it goes.

  Before the night was over each and every sailor played his part exactly once. At dawn when they started to divide the remaining coconuts, they found that there’s no extra coconut left for the monkeys. But the monkeys would not complain, nor would any of the sailors. They had their share alright.

  Historians, as one would expect, can be trusted for facts not for the figures. So whatever they would say about the values of S, C and M cannot be trusted entirely. But given the values of S, M and an interval for C one can identify possible values for C. As a programmer you only need to count the number of valid C values on a given range [low, high] inclusive.

Input

The first line of the input gives you the number of test cases, T (1 ≤ T ≤ 15). Then T test cases follow. Each of the test cases consists of four integers and is presented one in each line. The first integer gives you the number of sailors S (1 < S ≤ 100), then the next integer gives you the number of monkeys M (0 ≤ M < S). The next two integers will give you the value of low and high (0 ≤ low ≤ high ≤ 108 ).

Output

For each of the test cases, you need to print one line of output. The output for each test case starts with the test case number, followed by the number of valid C values in the range [low, high]. For the exact format of output, please consult the sample input/output section. Illustration: The first test case gives you 3 sailors, 2 monkeys and a range of [49, 50] to choose from. If you’d try to do the math in hand, you’d see that only 50 would satisfy the scenario. So the answer for the first test case has to be 1. Here’s the brief illustration:

Sailor # Total Coconuts His share Monkeys share Remaining Coconuts 1 50 16 2 32 2 32 10 2 20 3 20 6 2 12

Sample Input

3

3 2 49 50

4 2 5 10000

6 4 1 100000000

Sample Output

Case 1: 1

Case 2: 10

Case 3: 357

问题链接UVA10726 Coco Monkey

问题描述

  开始时有C个椰子,M个猴子,S个人。那天晚上,
  第1个人把椰子分成S份,剩下M个,给了M只猴子,自己拿了一份藏起来。
  第2个人把剩下的椰子分成S份,剩下M个,给了M只猴子,自己拿了一份藏起来。
  以此类推,直到那天结束。
  第2天,剩下的椰子正好分成S份,没有给猴子的。

  给出开始时椰子数量范围[L, R],求一开始的椰子数量有几种可能。

问题分析

  这是一个与递推有关的问题,按照递推式进行模拟。

  假设开始的时候有C个椰子,有s个人,按照题意把每个人做的事情都模拟一边就好了。每一步都要保证是合理的。有s个人,n个椰 子,给了m只猴子每只1个,并且分成s份,把自己的那一份藏起来,所以必须满足(n-m)%s==0。然后,椰子数量就变少了,少了(n-1)/s+1个。模拟要逆序模拟,并且要穷进各种可能。

  还需要找出递推式。如果最后的时候,椰子数量为remain,那么满足remain=k*S(k>=1为整数)。而前1个人操作前椰子数量为x=remain*s/(s-1)+m。利用这个递推式迭代计算即可。

程序说明:(略)

参考链接:(略)

题记:(略)

AC的C++语言程序如下:

/* UVA10726 Coco Monkey */

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

int solve(LL s, LL m, LL l, LL r)
{
    int ans = 0;
    // 试探:假设最后每个人分得i个椰子
    bool flag = true;
    for(int i = 1; flag; i++) {
        LL remain = s * i;
        if(remain % (s - 1))
            continue;
        // 模拟s人操作的过程:逆序递推
        int j;
        for(j = 1; j <= s; j++) {
              remain = remain * s / (s - 1) + m;
              if(remain > r) {
                  flag = false;
                  break;
              }
              if(remain % (s - 1) && j != s)
                  break;
        }
        if(j > s && remain >= l && remain <= r)
            ans++;
    }
    return ans;
}

int main()
{
    int t, caseno = 0;
    scanf("%d", &t);
    while(t--) {
        LL s, m, l, r;
        scanf("%lld%lld%lld%lld", &s, &m, &l, &r);
        printf("Case %d: %d\n", ++caseno, solve(s, m, l, r));
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/tigerisland45/article/details/81880697