bzoj|BZOJ 4325: NOIP2015 斗地主
斗地主是偏题
我真是醉了这道题
还是没搞清楚能不能四带四。。(四可以拆成俩对对子。。)
还有四带二能不能带王炸。。。
题意不清啊。。
最后看标程发现可以带王炸不能带四。。
bi了哈士奇了为什么可以带王炸却不能带俩个一样的对子。。
因为纠结这些个东西去年跪在这里没去打所以只拿了20还是30?
其实是一道搜索。。讲明白还是不难的。。
记得把尖刀(A)标为14,因为它可以连在王(King)后面
每一种状态先看看不出连牌要几次
先把四带二出完,再出三带一,最后加上单牌和对,记录并更新ans
然后枚举连牌并继续向下搜索
实现起来也是不难的,也不长。。加上读入/输出优化才七十几行
#include
#define g getchar()
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
inline ll read(){
ll x=0,f=1;
char ch=g;
for(;
ch<'0'||ch>'9';
ch=g)if(ch=='-')f=-1;
for(;
ch>='0'&&ch<='9';
ch=g)x=x*10+ch-'0';
return x*f;
}
inline void out(ll x){
int a[25],wei=0;
if(x<0)putchar('-'),x=-x;
for(;
x;
x/=10)a[++wei]=x%10;
if(wei==0){puts("0");
return;
}
for(int j=wei;
j>=1;
--j)putchar('0'+a[j]);
putchar('\n');
}
int ans,T,n;
int cnt[5],hand[16];
void dfs(int x){
if(x>ans)return;
int rest=0;
memset(cnt,0,sizeof(cnt));
for(int i=0;
i<15;
++i)cnt[hand[i]]++;
for(;
cnt[4];
){
cnt[4]--,rest++;
//炸弹
if(cnt[2]>=2)cnt[2]-=2;
//能不能带二
else if(cnt[1]>=2)cnt[1]-=2;
}
for(;
cnt[3];
){
cnt[3]--,rest++;
//三张牌
if(cnt[2])cnt[2]--;
//能不能带一
else if(cnt[1])cnt[1]--;
}//我在思考把三带一和四带二写成子程序是不是更简洁?
if(hand[0]&&hand[1]&&cnt[1]>=2)--rest;
//看看剩下的单牌有没有王炸
rest+=cnt[1]+cnt[2];
ans=min(rest+x,ans);
for(int i=3,j;
i<15;
++i){//单顺子
for(j=i;
hand[j]&&j<15;
++j){
hand[j]--;
if(j-i+1>=5)dfs(x+1);
//如果多于5张向下搜索
}
for(;
j>i;
)hand[--j]++;
}
for(int i=3,j;
i<=15;
++i){//双顺子
for(j=i;
hand[j]>=2&&j<15;
++j){
hand[j]-=2;
if(j-i+1>=3)dfs(x+1);
}
for(;
j>i;
)hand[--j]+=2;
}
for(int i=3,j;
i<=15;
++i){//三顺子
for(j=i;
hand[j]>=3&&j<15;
++j){
hand[j]-=3;
if(j-i+1>=2)dfs(x+1);
}
for(;
j>i;
)hand[--j]+=3;
}//我在思考是不是把顺子什么写个子程序会更简洁?
}
int main(){
T=read();
n=read();
for(;
T--;
){
ans=n;
memset(hand,0,sizeof(hand));
for(int i=1;
i<=n;
++i){
int x=read(),y=read();
if(x==0)hand[y-1]++;
//Joker要分开存,因为它们并不能组成对牌
else if(x==1)hand[14]++;
else hand[x]++;
}
dfs(0);
out(ans);
}
return 0;
}
【bzoj|BZOJ 4325: NOIP2015 斗地主】发现一个人程序写错然而AC了让我很难过,而且UO(钩)的斗地主因为数据是随机的所以不能Hack。。
推荐阅读
- 【BZOJ】4316:|【BZOJ】4316: 小C的独立集 静态仙人掌
- 类欧几里得算法|[类欧几里得算法 数论] BZOJ 2987 Earthquake
- 线段树|[类欧几里得算法 线段树] BZOJ 1938 [CROATIAN2010] ALADIN
- bzoj|Bzoj3817:Sum
- BZOJ|BZOJ2763[JLOI2011]飞行路线【分层图最短路】
- BZOJ3817(Sum(类欧几里得))
- 类欧几里得|bzoj2987 Earthquake 类欧几里得
- 题解|[BZOJ3817] Sum
- bzoj2712 -- 类欧几里得算法
- Bzoj|[BZOJ2187][fraction][类欧几里得算法]