C. Card Game

Consider a game with nn cards (nn is even). Each card has a number written on it, between 11 and nn. All numbers on the cards are different. We say that a card with number xx is stronger than a card with number yy if x>yx>y.

Two players, Alex and Boris, play this game. In the beginning, each of them receives exactly n2n2 cards, so each card belongs to exactly one player. Then, they take turns. Alex goes first, then Boris, then Alex again, and so on.

On a player's turn, he must play exactly one of his cards. Then, if the opponent doesn't have any cards stronger than the card played, the opponent loses, and the game ends. Otherwise, the opponent has to play a stronger card (exactly one card as well). These two cards are removed from the game, and the turn ends. If there are no cards left, the game ends in a draw; otherwise it's the opponent's turn.

Consider all possible ways to distribute the cards between two players, so that each of them receives exactly half of the cards. You have to calculate three numbers:

  • the number of ways to distribute the cards so that Alex wins;
  • the number of ways to distribute the cards so that Boris wins;
  • the number of ways to distribute the cards so that the game ends in a draw.

You may assume that both players play optimally (i. e. if a player can win no matter how his opponent plays, he wins). Two ways to distribute the cards are different if there is at least one card such that, in one of these ways, it is given to Alex, and in the other way, it is given to Boris.

For example, suppose n=4n=4, Alex receives the cards [2,3][2,3], and Boris receives the cards [1,4][1,4]. Then the game may go as follows:

  • if Alex plays the card 22, then Boris has to respond with the card 44. Then, Alex's turn ends, and Boris' turn starts. Boris has only one card left, which is 11; he plays it, and Alex responds with the card 33. So, the game ends in a draw;
  • if Alex plays the card 33, then Boris has to respond with the card 44. Then, Alex's turn ends, and Boris' turn starts. Boris has only one card left, which is 11; he plays it, and Alex responds with the card 22. So, the game ends in a draw.

So, in this case, the game ends in a draw.

Input

The first line contains one integer tt (1≤t≤301≤t≤30) — the number of test cases.

Then, tt lines follow. The ii-th line contains one even integer nn (2≤n≤602≤n≤60).

Output

For each test case, print three integers:

  • the number of ways to distribute the cards so that Alex wins;
  • the number of ways to distribute the cards so that Boris wins;
  • the number of ways to distribute the cards so that the game ends in a draw.

Since the answers can be large, print them modulo 998244353998244353.

Example

input

Copy

 

5

2

4

6

8

60

output

Copy

1 0 1
3 2 1
12 7 1
42 27 1
341102826 248150916
 

思路分析:

如果我们的先手拿到了最大的牌,毫无疑问,游戏结束了,总情况数是在n-1张牌数中后手拿到(n/2)张牌

如果我们的先手没有拿到最大的牌,那么第一回合肯定没有结束游戏,这时候换成了原来的后手变成先手,考虑它赢的情况,拿我们总牌数(注意剩余n-2)张牌,跳出里面最大的给现在所谓的先手就是第二回合所谓的先手赢的情况,拿我们的总情况c(n-2,(n-2)/2)减去它赢的情况和平局情况。

我们上述两种情况相加就是我们的先手赢的情况

设n=2*i

    f[i] = (c[2 * i - 1][i] + (c[2 * i - 2][i - 1] - f[i - 1] - 1 + mod) % mod) % mod;

   这个式子表示先手直接赢的情况,加上后手输的情况

i从1开始递推到n/2就是我们的答案了

#include<iostream>
#include<cstring>
using namespace std;
using LL = long long;
const int maxn = 200, mod = 998244353;
int c[maxn][maxn];
int f[maxn];
int main() {
	cin.tie(0);
	cout.tie(0);
	ios::sync_with_stdio(0);
	for(int i = 0; i < maxn; i++)
		for(int j = 0; j <= i; j++)
			if (!j) c[i][j] = 1;
			else c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;//预处理出来从i个里面跳出来j个的组合数
	f[1] = 1;
	for(int i = 2; i <= 30; i++)//预处理出来先手获胜的情况
		f[i] = (c[2 * i - 1][i] + (c[2 * i - 2][i - 1] - f[i - 1] - 1 + mod) % mod) % mod;
			//先手拿最大,后手一共拿这么多牌++++      后手(第二轮的先手)先拿牌,最大的,减去总牌数为2*(i-1)先手赢和平局的次数
	int T;
	cin >> T;
	while(T--) {
		int n;
		cin >> n;
		n /= 2;
		cout<<f[n]<<' '<<(c[2 * n][n]-f[n]-1+mod)%mod<<' '<<1<<'\n';
	}
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include <stdio.h> #include <stdlib.h> #define CARD_NUM 52 #define PLAYER_NUM 2 typedef struct Card { int number; char suit; } Card; void initializeDeck(Card deck[]) { int i, j, count = 0; for (i = 1; i <= 13; i++) { for (j = 0; j < 4; j++) { deck[count].number = i; switch (j) { case 0: deck[count].suit = 'S'; // Spade break; case 1: deck[count].suit = 'H'; // Heart break; case 2: deck[count].suit = 'D'; // Diamond break; case 3: deck[count].suit = 'C'; // Club break; } count++; } } } void shuffleDeck(Card deck[]) { int i, j; Card temp; for (i = 0; i < CARD_NUM; i++) { j = rand() % CARD_NUM; temp = deck[i]; deck[i] = deck[j]; deck[j] = temp; } } void playGame(Card deck[]) { Card player1[CARD_NUM/2]; Card player2[CARD_NUM/2]; int currentPlayer = 1; // Player 1 starts the game int table[CARD_NUM]; int tableSize = 0; int i, j, k, found; // Distribute cards to players for (i = 0; i < CARD_NUM / 2; i++) { player1[i] = deck[i]; player2[i] = deck[i + CARD_NUM / 2]; } // Main game loop while (1) { if (currentPlayer == 1) { printf("Player 1's turn:\n"); printf("Player 1 plays: %d%c\n", player1[0].number, player1[0].suit); table[tableSize++] = player1[0].number; // Check if there are any cards to take from the table found = 0; for (i = 0; i < tableSize; i++) { if (table[i] == player1[0].number) { found = 1; break; } } if (found) { printf("Player 1 takes: "); for (j = i; j < tableSize; j++) { printf("%d%c ", table[j], player1[0].suit); } printf("\n"); // Remove cards from the table for (j = i; j < tableSize; j++) { for (k = j; k < tableSize - 1; k++) { table[k] = table[k + 1]; } tableSize--; } } // Remove card from player's hand for (i = 0; i < CARD_NUM / 2 - 1; i++) {
最新发布
07-14

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值