2018年省赛热身赛第10场-A - Dogs and Cages(没有什么是打表 + 找规律不能解决的)

Problem Description

Jerry likes dogs. He has N dogs numbered 0,1,...,N−1. He also has N cages numbered 0,1,...,N−1. Everyday he takes all his dogs out and walks them outside. When he is back home, as dogs can’t recognize the numbers, each dog just randomly selects a cage and enters it. Each cage can hold only one dog.
One day, Jerry noticed that some dogs were in the cage with the same number of themselves while others were not. Jerry would like to know what’s the expected number of dogs that are NOT in the cage with the same number of themselves.

Input

The first line of the input gives the number of test cases, T. T test cases follow.
Each test case contains only one number N, indicating the number of dogs and cages.
1≤T≤105
1≤N≤105

Output

For each test case, output one line containing “Case #x: y”, where x is the test case number (starting from 1) and y is the expected number of dogs that are NOT in the cage with the same number of itself.
y will be considered correct if it is within an absolute or relative error of 10−6 of the correct answer.

Sample Input

2

1

2

Sample Output

Case #1: 0.0000000000

Case #2: 1.0000000000

Hint

In the first test case, the only dog will enter the only cage. So the answer is 0. In the second test case, if the first dog enters the cage of the same number, both dogs are in the cage of the same number, the number of mismatch is 0. If both dogs are not in the cage with the same number of itself, the number of mismatch is 2.

这几天被找规律给折腾的,没有什么是我 打表 + 找规律不能解决的!今天天训练赛状态还是不错的,就是刚开始玩手机玩过头了晚了好几分钟开始!谨记,下次勿犯!

思路:

这道题简化成有n个数字(1,2,...,n),dog的排列方式有多少种就是n的全排列有多少种,就是n的阶乘,这里就是看n个数全排列之后,有几个跟cage的顺序(也就是1-n)的顺序是吻合的,打几个表,规律是a[i] = i - 1,还是挺好找的.

【通过代码】

#include <stdio.h>
int main()
{
    int n,t = 0,res,repeat;
    scanf("%d",&repeat);
    while(repeat--)
    {
        scanf("%d",&n);
        t++;
        res = n - 1;
        printf("Case #%d: %d.0000000000\n",t,res);
    }
}

【打表代码】

#include <iostream>
#include <cstdio>
using namespace std;
int b[100005],c[1000005];
int i,t ,sum ;
void permutation(int k, int n, int a[])
{
    //递归到底层
    if(k == n-1)
    {
        for(i = 0; i < n; i ++)
        {
            b[i] = a[i];//全排列这里cout<<a[i]<<endl;就行,可以手动数有几个吻合的,我下面写了一小段代码感觉还是手数来的快,毕竟是找规律,数两个差不多就得了
            t = 0;
            while(b[i] != 0)
            {
                c[t++] =b[i] % 10;
                b[i] = b[i] / 10;
            }
            for(int j = 0; j < t;j++)
            {
                if(c[j] != j + 1)
                {
                    sum ++;
                }
            }
            //////上面的到注释都没必要,不过机数更保险点,验证的数字可以多一点
        }


    }
    else
    {
        for(int i = k; i < n; i ++)
        {
            int temp = a[k];
            a[k] = a[i];
            a[i] = temp;

            //交换后递归下一层
            permutation(k+1, n, a);

            //保证每一层递归后保持上一层的顺序
            temp = a[k];
            a[k] = a[i];
            a[i] = temp;
        }
    }


}
int main()
{
    int a[100];
    int n;

    scanf("%d", &n);
    sum =0;
    for(int i = 0; i < n; i ++)
        a[i] = i+1;

    permutation(0, n, a);
    cout<<sum<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/hzyhfxt/article/details/82025521
今日推荐