P2348 三国杀I(洗牌&发牌)

https://www.luogu.com.cn/problem/P2348

题目自己看一看吧,太长了不太好复制,

(本题出自洛谷P2348)

~~一开始想去a猪国杀(被吓到了)~~
于是我就来a这个题了
其实还是简单一点的模拟
三个难点
1.对于每一张牌的输入
2.洗牌时的操作
3.最后的输出
### 逐个解决
1.输入的时候利用一个结构体对于这个进行定义
```cpp
struct pai{//利用结构体对于每一张牌便于操作
string c;
string s;
```
把c字符串看做两东西(color+number)
然后s字符串是type
(不用考虑每一张牌有什么用,干什么的,上面的一群东西都是吓人的,我们只要知道输入的是字符就可以了)
2.洗牌的时候(是一种大佬级别的洗牌,那种中分之后一叠一)
(洗牌方式:k/2+1,1,k/2+2,2,k/2+3,3, ... ,k,k/2(可以有奇数张牌,最后一张牌将被无耻的度娘吃掉))要对次数进行考虑,我利用的是while循环(每次--)
```cpp
while(cishu--)
```
3.最后的分牌的时候就可以遵循题目给你的方法啊
第i张牌给第(i-1)%n+1个人
如果这第(i-1)%n+1个人是P,那么就把这张牌压入数组就好了啊
最后的一个for循环便于输出
# ac代码如下
```cpp
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define itn int//防止手滑操作
using namespace std;
struct pai{//利用结构体对于每一张牌便于操作
string c;
string s;
}paiku[100005],b[100005],ans[100005];
int main()
{
int n,m,cishu,p;
cin>>n>>m>>cishu>>p;
if(m<n*4)//牌不够
{
printf("Error:cards not enough");
return 0;//对于牌不够的情况,直接结束程序,停止操作
}
m=m/2*2;//可以有奇数张牌,最后一张牌将被无耻的度娘吃掉
for(int i=1;i<=m;i++)
{
cin>>paiku[i].c>>paiku[i].s;
}//建牌库;
while(cishu--)
{
int j=1;
for(int i=1;i<=m-1;i+=2,j++)//在期间对于j进行++操作
{
b[i]=paiku[m/2+j];
b[i+1]=paiku[j];
}
for(int i=1;i<=m;i++)
paiku[i]=b[i];//重新存回paiku数组 (方便下一次操作)
}
int j=1;
for(int i=1;i<=m&&j<5;i++)//标记一下对于j的要求
if((i-1)%n+1==p)//这是分牌的操作,基本 这是题目给的(从第1张牌开始,第i张牌给第(i-1)%n+1个人)
{
ans[j]=paiku[i];
j++;
}
for(int i=1;i<=4;i++)
cout<<ans[i].c<<' '<<ans[i].s<<endl;
//最后按要求输出就ok了
return 0;
}

```

我在里面加了一个对于牌数的特判,大约是在第16--20行。
这个题光看牌面的话还是有点吓人的,但是如果你跳出来,不去考虑三国杀得规则的话,其实就是一个起名复杂一点的分扑克,
(吐槽一下,里面的那个j是真的恶心,试了好多遍才试出真正的位置)
博客写的不是太好,直接复制过来的,(我自己写的)

原博客见https://www.luogu.com.cn/blog/840-114/solution-p2348

 

原文地址:https://www.cnblogs.com/--840-114/p/12938094.html