LuoguP2348 三国杀I(洗牌&发牌) 题解
作者:互联网
Content
浓缩版:将牌库里的 \(k\) 张牌洗 \(m\) 次,然后将其分发给 \(n\) 个玩家,问第 \(p\) 号玩家的 \(4\) 张牌都有哪些。
完整版:Link
Solution
直接对照题意模拟一遍即可。反正写过近 \(200\) 行的模拟代码,这样的模拟还算是简单的了。
我们在输入完 \(n,k,m,p\) 以后可以直接判断出牌是否够。因为每个人都要有 \(4\) 张牌,所以牌库里面必须要有足够 \(n\) 个人有四张牌的储存数量。也就是说,\(k\geqslant 4n\)。所以,如果 \(k<4n\) 的话牌肯定不够,于是直接退出程序。
牌够的话就继续下面的洗牌和发牌过程,由题意我们可以明显的看出,这道题目中牌的花色、点数和类型纯粹就是用来作为输入输出的载体,没有什么实质性的用处(实质性的用处可以参考P2482)。那么直接按照题目里的要求洗就是了。
首先要注意的是牌库里储存的牌的数量的问题,因为它可能是奇数,所以我们应该按照题目里的要求直接忽略掉它。那么如何存储洗过之后的牌呢?我们在这里考虑另起一个结构体来存储,然后将所有的信息全部用来覆盖掉原来的信息。
最后就是发牌了,因为题目中只需要知道第 \(p\) 个人的所有牌,所以只需要当轮到 \(p\) 的时候直接输出当前的牌就可以了。题目中给了我们这样的公式:
第 \(i\) 张牌分给第 \([(i-1)\mod n+1]\) 号玩家。
所以直接套公式,然后看它等于 \(p\) 的时候直接输出牌的所有信息即可。
Code
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
struct cd {
string cn, t;
}c1[100007], c2[100007];
int n, k, m, p;
int main() {
scanf("%d%d%d%d", &n, &k, &m, &p);
for(int i = 1; i <= k; ++i)
cin >> c1[i].cn >> c1[i].t;
if(k < n * 4) {
printf("Error:cards not enough");
return 0;
}
if(k % 2) k--;
while(m--) {
for(int i = 1; i <= k - 1; i += 2) {
c2[i] = c1[k / 2 + (i + 1) / 2];
c2[i + 1] = c1[(i + 1) / 2];
}
for(int i = 1; i <= k; ++i)
c1[i] = c2[i];
}
int cnum = 0;
for(int i = 1; i <= k; ++i)
if((i - 1) % n + 1 == p) {
cnum++;
if(cnum > 4) break;
cout << c1[i].cn << ' ' << c1[i].t << '\n';
}
return 0;
}
标签:题目,int,题解,d%,张牌,LuoguP2348,include,发牌 来源: https://www.cnblogs.com/Eason-AC/p/15725101.html