week6 限时模拟 掌握魔法の东东 II

题目

样例输入1

5 2
1 0 3 1

样例输出1

0 8 0 0 0 12 0 36 0

样例输入2

25 4
0 0 24 3

样例输出2

0 0 0 2 18 1656 644 36432 113344

 

思路

我起初看到这道题觉得三重循环暴力判断应该就可以,然后看见限时200ms就放弃了(事实证明不会超时的)。然后,我就采用了一种更简单粗暴的算法!就是,用笔算的方法让计算机进行计算...强行把一道枚举写成了排列组合!前几个比较容易判断,简单列举后面的各类情况(如果x1、x2相等,x1与x2均假设为1,如果不等,则x1假设为1,x2假设为2):

5.三带二

(1)x1 == x2    11,xxx   +   111,xx

(2)x1 !=  x2    111,22    +   11,222

6.两对

(1)x1 == x2    11,xx,y

(2)x1 !=  x2    11,22,x   +   1,22,xx   +   11,2,xx

7.三条

(1)x1 == x2    111,x,y

(2)x1 !=  x2    1,222,x   +   111,2,x   +   1,2,xxx

8.一对

(1)x1 == x2    111,x,y,z

(2)x1 !=  x2    1,2,xx,y   +   11,2,x,y   +   1,22,x,y

注意

序列号小的情况不会被序列号大的情况包含在内,也就是说,每“一手牌”只能属于一种牌面。

 

代码

#include <iostream>
#include<algorithm>
using namespace std;
int A, B;
int con[10];

int main()
{
	memset(con, 0, sizeof con);
	cin >> A >> B;
	int a1, b1, a2, b2;
	cin >> a1 >> b1 >> a2 >> b2;

	if (a1 > a2)
	{
		swap(a1, a2);
		swap(b1, b2);
	}
	int mov = min(min(a1 + 5, A) - a2, a1 - max(a2 - 5, -1));
	int x = min(mov, A - 4);
	//cout << "x:" << x << endl;
	if (A >= 5 && a2 - a1 < 5 && a1 != a2 && b1 == b2)//con1,同花顺
		con[1] = x;

	if (A >= 5 && a2 - a1 < 5 && a1 != a2)//con2,顺子
		con[2] = x*B*B*B - con[1];

	if (A >= 5 && b1 == b2)//con3,同花
		con[3] = (A - 2)*(A - 3)*(A - 4)/6 - con[1];

	if (B == 4)//con4,炸弹
	{
		if (a1 == a2)
			con[4] = 1;
		else
			con[4] = 2;
	}

	if (B > 2)//con5,三带二
	{
		if (a1 == a2)
		{
			if (B == 4)
				con[5] = 2 * (A - 1)*B*(B - 1) / 2 + 4 * (A - 1);
			else
				con[5] = (A - 1)*B*(B - 1) / 2 + (A - 1);
		}
		else
		{
			if (B == 4)
				con[5] = 18;
			else
				con[5] = 4;
		}
	}

	if (B > 1)//con6,两对
	{
		if (a1 == a2)
			con[6] = (B - 1)*B / 2 * (A - 1)* (A - 2)*B;
		else
			con[6] = (B - 1)*(B - 1)*(A - 2)*B + 2 * (B - 1)*(B - 1)*B / 2 * (A - 2);
	}

	//con7,三条
	if (B > 2) 
	{
		if (a1 == a2)
			con[7] = (B - 2) * (A - 1)*B*(A - 2)*B / 2;
		else
			if (B == 4)
				con[7] = 2 * 3 * (A - 2)*B + 4 * (A - 2);
			else
				con[7] = 2 * (A - 2)*B + (A - 2);
				
	}


	//con8,一对
	if (B > 1)
	{
		if (a1 == a2)
			con[8] = (A - 1)*B * (A - 2)*B * (A - 3)*B / 6;
		else
			con[8] = 2 * (B - 1) * (A - 2)*B*(A - 3)*B /2  + B * (B - 1) / 2 * (A - 2)*(A - 3)*B;
	}


		x = A * B - 2;
		con[9] = x * (x - 1)*(x - 2) / 6;
		
		for (int i = 1; i <= 8; i++)
			con[9] -= con[i];

		for (int i = 1; i <= 9; i++)
			cout << con[i] << " ";

		//system("Pause");
		
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值