湖南工业大学创新实验室2015年新生赛(一)1001(重开)

A simple problem I

Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 70   Accepted Submission(s) : 33

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

实话告诉你们,ikids最喜欢下棋了,什么棋他都爱下!不过相比于下棋,作为一个ACMer,他更喜欢研究棋,因为好多题目都是涉及各种棋的(ORZ),这不,最近他就迷上了国际象棋里的车,现在让我来跟你讲讲车的在棋盘中的规则吧!

作为仅次于皇后的棋子,它能竖着走,还能横着走(其实和中国象棋里的車是一样的..hahahah),但是当它遇到处于同行同列的车的时候,它就喜欢把它吃了,如下图所示。


R2、R3就冲突了!这可不是ikids希望的!!!那么,问题来了:
给定两个整数n和k,代表n*n的棋盘,和k个车,问你有多少种摆放,使得没有两个車会出现如同R2,R3这种情况!

Input

第一行输入一个T(T<=100000),代表测试数据组数。
对于每一组,输入两个整数n,k;代表n*n的棋盘,k个车;n<=30,k <=n^2

Output

对于每组数据,输出ans,ans为多少种摆放。

数据保证不会超出unsigned long long int。

Sample Input

8
1 1
2 4
3 1
4 1
4 2
4 3
4 4
4 5

Sample Output

1
0
9
16
72
96
24
0
组合数学,ans=A(n,m)*C(n,m) n行放k个车,n列也能放k个车,两者摆放则乘以K!
因为做的时候已经结束了,所以借用链接下面的代码
http://blog.csdn.net/u013615904/article/details/49967753
#include<iostream>
#include<cstdio>
#define ULL unsigned long long
using namespace std;
const int maxn=35;
ULL dp[maxn][maxn*maxn];
ULL C(int n,int m)
{
    if(n<m) return 0;
    ULL ans=1;
    for(int i=0;i<m;i++) ans=ans*(ULL)(n-i)/(ULL)(i+1);
    return ans;
}
ULL A(int n,int m)
{
    if(n<m) return 0;
    ULL ans=1;
    for(int i=0;i<m;i++) ans*=(ULL)(n-i);
    return ans;
}
ULL fuck(int n,int k)
{
    if(dp[n][k]) return dp[n][k];
    return dp[n][k]=A(n,k)*C(n,k);
}
int main()
{
    //freopen("in.txt","r",stdin);
    int n,k,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&k);
        printf("%I64u\n",fuck(n,k));
        //printf("%I64u\n",A(n,k));
        //printf("%I64u\n",C(n,k));
    }
    return 0;
}

  

posted @ 2015-11-27 19:12  樱花落舞  阅读(334)  评论(0编辑  收藏  举报