【第6週限定シミュレーション】A-Master of Magic II

A - 掌握魔法の东东 II

トピック:

Ruishenのカードゲームから戻った後、Dongdongは苦痛を感じ、彼のカードスキルを練習することに決め、最終的にギャンブラーになりました!
東洞にはA×Bのトランプがあります。各トランプには、サイズ(整数、a、範囲0〜A-1)とスーツ(整数、b)、範囲
0〜B -1があります。トランプも異なります。ユニークであり、同じサイズで同じカードが2枚あることはありません。
「片手」とは、5枚の異なるカードが手札にあることを意味します。これらの5枚のカードは、表と裏の順番ではありません。カードタイプを形成できます。9種類のカードタイプを定義しました。以下は9種類のカードタイプのルールです。「低いシリアル番号の優先順位」を使用してカードタイプを一致させます。つまり、「最初の手」が最初から最初に出会います。カードタイプルールは、その「カード番号」(1〜9に属する整数)です。

1.ストレートフラッシュ:ルール2と3の両方を満たします
。3
.ストレート:サイズx、x + 1、x + 2、x + 3、x + 4の5枚のカード3.ストレート:すべて5枚のカード同じスーツ
4.爆弾:5枚のうち4枚のカードは同じサイズです
。5. 3つのベルト:5枚のうち2枚のカードは同じサイズで、他の2枚のカードも同じサイズです
。6 .2ペア:5枚のカード(そのうち2枚は同じサイズ、他の3枚のカードのうち2枚は同じサイズ)
7. 3枚のカード:5枚のカード、同じサイズの3枚。81組
: 5枚のカードのうち、2枚は同じサイズです
9.すみません:このハンドは、上記のタイプのいずれも満たしていません。

今、ドンドンはA×Bのトランプから2枚のカードを取ります!これらは(a1、b1)と(a2、b2)です(aはサイズ、bはスーツです)では
、残りのカードからさらに3枚のランダムなカードを取ります!手を作ろう!
実際、コードをプレイすることに加えて、ドンドンは余暇にはまだ魔術師です。今、彼は彼の将来の可能性、つまり彼が得る「最初の手」の可能性を予測したいと考えています。「カード番号(整数、1から9まで)「このハンドのハンドタイプを示すために、彼には将来9通りの可能性がありますが、可能な各スキームの数は異なります。
これで、ドンドンのアゴモの目はなくなりました。アゴモが9種類それぞれのオプションの数を数えるのを手伝う必要があります。

入力

行1には整数AおよびBが含まれています(5≤A≤25、1≤B≤4)。

行2には、整数a1、b1、a2、b2(0≤a1、a2≤A-1、0≤b1、b2≤B-1(a1、b1)≠(a2、b2))が含まれています。

出力

1行を出力します。この行には9つの整数があり、各整数は9つのカードタイプの数を表します(カード番号の小さい順から大きい順)。

入力例

5 2
1 0 3 1

25 4
0 0 24 3

出力例

0 8 0 0 0 12 0 36 0

0 0 0 2 18 1656 644 36432 113344

アイデアと実践:

コードは2つの部分に分かれています。バックトラック()は再帰的にトレースしてすべての直接カードを探し、チェック()はカードのタイプを判別します。backtrack()は、カードを配列paiに再帰的に追加します。カードの数が5に達したら、カードを配列pにコピーし、check()を呼び出して、配列pの5つのカードがどのカードタイプに属しているかを判別し、符号配列を更新します。

要約:

元のpai配列をチェック()に使用することはできません。並べ替えは順序を乱します。

コード:

#include <stdio.h>
#include <map>
#include <algorithm>
using namespace std;

const int MAXA = 26, MAXB = 4;
int A, B, c, sign[10];
struct Pai{
	int a, b;
	Pai(){}
	Pai(int _a, int _b):a(_a), b(_b){}
	bool operator<(const Pai& pai) const {
		if(a != pai.a) return a < pai.a;
		return b < pai.b;
	}
	void output(){ printf("%d %d\n", a, b); }
}p[6], pai[6];
map<Pai, bool> isUse;

void check(){
	bool two = 1, three = 1;
	map<int, int> cnt;
	sort(pai+1, pai+6);
	for(int i = 1; i <= 5; ++i){
		cnt[pai[i].a]++;
		if(i >= 2){
			if(pai[i].a != pai[i-1].a + 1) two = 0;
			if(pai[i].b != pai[i-1].b) three = 0;
		}
	}
	if(two && three){ sign[1]++; return; }
	if(two){ sign[2]++; return; }
	if(three){ sign[3]++; return; }
	map<int, int>::iterator iter;
	iter = cnt.begin();
	int num[5], n = 0;
	while(iter != cnt.end()){
		num[n++] = iter->second;
		iter++;
	}
	sort(num, num+n, greater<int>());
	if(num[0] == 4) { sign[4]++; return; }
	else if(n == 2 && num[0] == 3 && num[1] == 2) { sign[5]++; return; }
	else if(n == 3 && num[0] == 2 && num[1] == 2) { sign[6]++; return; }
	else if(n == 3 && num[0] == 3 && num[1] == 1) { sign[7]++; return; }
	else if(n == 4 && num[0] == 2) { sign[8]++; return; }
	else { sign[9]++; return; }
}

void backtrack(int a, int b, int s){
	if(s >= 5){
		for(int i = 1; i <= 5; ++i){
			pai[i] = p[i];
		}
		check();
		return;
	}
	for(int k = a*B+b+1; k < A*B; ++k){
		int i = k / B, j = k % B;
		if(!isUse[Pai(i, j)]){
			p[s+1] = Pai(i, j);
			isUse[p[s+1]] = 1;
			backtrack(i, j, s+1);
			isUse[p[s+1]] = 0;
		}
	}
}

int main(){
	scanf("%d %d", &A, &B);
	scanf("%d %d %d %d", &p[1].a, &p[1].b, &p[2].a, &p[2].b);
	for(int i = 1; i <= 9; ++i) sign[i] = 0;
	isUse[p[1]] = 1; isUse[p[2]] = 1;
	c = 0; backtrack(0, -1, 2);
	for(int i = 1; i <= 9; ++i) printf("%d ", sign[i]);
	printf("\n");
	return 0;
}
公開された10元の記事 ウォンの賞賛0 ビュー231

おすすめ

転載: blog.csdn.net/weixin_44898140/article/details/105297549