zoukankan      html  css  js  c++  java
  • [CSP-S模拟测试]:棋盘(数学+高精度)

    题目描述

    在一个大小为$N imes N$的棋盘上,放置了$N$个黑色的棋子。并且,对于棋盘的每一行和每一列,有且只有一个棋子。
    现在,你的任务是再往棋盘上放置$N$个白色的棋子。显然,白色棋子不能与黑色棋子重合。在此基础上,放置的方式还需要满足:对于棋盘的每一行和每一列,有且只有一个白色棋子。
    当然,放置的方式有很多种,你只需要输出不同的放置方案数即可。


    输入格式

    输入文件为$board.in$。
    第一行包含一个正整数$N$。
    接下来$N$行,每行$N$个整数用于描述棋盘。$0$表示这个位置是空的,而$1$表示这个位置有一个黑棋子。


    输出格式

    输出文件为$board.out$。
    一行一个整数,表示合法的放置方案数。


    样例

    样例输入:

    2
    0 1
    1 0

    样例输出:

    1


    数据范围与提示

    对于$20\%$的数据,满足$Nleqslant 10$。
    对于$60\%$的数据,满足$Nleqslant 20$。
    对于$100\%$的数据,满足$1leqslant Nleqslant 200$。


    题解

    对于每一列,哪一行放黑子无所谓,那个就是逗你开心的。

    先说一下我在考场上的思路,我想到了容斥和组合数。

    首先,如果不考虑黑子,那么我们有$N!$种放法。

    然后我们可以考虑有黑子的情况,设$f[i]$表示至少有$i$列合法的方案数,此处的合法是指白子和黑子没有放到一起,则:

    $$f[i]=(N-i)! imes C_N^i$$

    先来解释式子,$(N-i)!$表示剩下的我们还是可以随便选,$C_N^i$则表示在$N$列中选出$i$列。

    最后答案就是$sum limits_{i=1}^N (-1)^i f[i]$。

    然而这个式子太麻烦了,于是$170$行各种高精多和一就爆炸了……

    下面来讲官方题解,问题就是让求$N$个数的错排方案数,那么直接用递推式即可:

    $$ans_n=(ans_{n-1}+ans_{n-2}) imes (n-1)$$

    时间复杂度:$Theta(n^2)$。

    期望得分:$100$分。

    实际得分:$100$分。


    代码时刻

    #include<bits/stdc++.h>
    using namespace std;
    int n;
    long long f[201][1000],flag1,flag2;
    void pls(int x)
    {
    	int jw=0;
    	f[x][0]=f[x-1][0];
    	for(int i=1;i<=f[x][0];i++)
    	{
    		f[x][i]=f[x-1][i]+f[x-2][i]+jw;
    		jw=f[x][i]/10;
    		f[x][i]%=10;
    	}
    	for(int i=f[x][0]+1;i;i++)
    	{
    		if(!jw)break;
    		f[x][i]+=jw;
    		jw=f[x][i]/10;
    		f[x][i]%=10;
    		f[x][0]=i;
    	}
    }
    void che(int x)
    {
    	flag2=0;
    	for(int i=1;i<=f[x][0];i++)
    	{
            flag1=f[x][i]*(x-1)+flag2;
            f[x][i]=flag1%10;
            flag2=flag1/10;
        }
        if(flag2)f[x][++f[x][0]]=flag2;
    }
    int main()
    {
    	scanf("%d",&n);
    	f[1][1]=0;
    	f[2][1]=1;
    	f[2][0]=1;
    	for(int i=3;i<=n;i++)
    	{
    		pls(i);
    		che(i);
    	}
        cout<<f[n][f[n][0]];
        while(--f[n][0])
        {
    	    cout.fill('0');
    		cout<<setw(1)<<f[n][f[n][0]];
    	}
    	return 0;
    }
    

    rp++

  • 相关阅读:
    使用VSCode创建简单的Razor Webapp--1.入门
    ASP.NET Razor 常用示例
    ASP.NET Razor 语法
    ASP.NET Razor简介
    EF CodeFirst 一对一、一对多、多对多关系
    mysql外键
    EF CodeFirst 之 Fluent API
    替换JDK 对eclipse的影响?
    mysql数据库,安装 !创建!...详解!
    Apache的commons工具类
  • 原文地址:https://www.cnblogs.com/wzc521/p/11649721.html
Copyright © 2011-2022 走看看