博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
1028: [JSOI2007]麻将 - BZOJ
阅读量:5172 次
发布时间:2019-06-13

本文共 2595 字,大约阅读时间需要 8 分钟。

Description

麻将是中国传统的娱乐工具之一。麻将牌的牌可以分为字牌(共有东、南、西、北、中、发、白七种)和序数牌(分为条子、饼子、万子三种花色,每种花色各有一到九的九种牌),每种牌各四张。在麻将中,通常情况下一组和了的牌(即完成的牌)由十四张牌组成。十四张牌中的两张组成对子(即完全相同的两张牌),剩余的十二张组成三张一组的四组,每一组须为顺子(即同花色且序数相连的序数牌,例如条子的三、四、五)或者是刻子(即完全相同的三张牌)。一组听牌的牌是指一组十三张牌,且再加上某一张牌就可以组成和牌。那一张加上的牌可以称为等待牌。  在这里,我们考虑一种特殊的麻将。在这种特殊的麻将里,没有字牌,花色也只有一种。但是,序数不被限制在一到九的范围内,而是在1到n的范围内。同时,也没有每一种牌四张的限制。一组和了的牌由3m + 2张牌组成,其中两张组成对子,其余3m张组成三张一组的m组,每组须为顺子或刻子。现给出一组3m + 1张的牌,要求判断该组牌是否为听牌(即还差一张就可以和牌)。如果是的话,输出所有可能的等待牌。
Input
包含两行。第一行包含两个由空格隔开整数n, m (9<=n<=400, 4<=m<=1000)。第二行包含3m + 1个由空格隔开整数,每个数均在范围1到n之内。这些数代表要求判断听牌的牌的序数。
Output
输出为一行。如果该组牌为听牌,则输出所有的可能的等待牌的序数,数字之间用一个空格隔开。所有的序数必须按从小到大的顺序输出。如果该组牌不是听牌,则输出"NO"。
Sample Input
9 4
1 1 2 2 3 3 5 5 5 7 8 8 8
Sample Output
6 7 9

 

囧,我一直以为以为直接搜索就行了,没有算时间

原来要贪心的选,先枚举要胡的,然后把能做刻子的都做刻子,剩下的都只能做顺子,扫一遍就出来了

代码就坑爹了,发现这个贪心之后,我直接把我暴力枚举的那一段中枚举刻子的个数的地方改成枚举最大刻子数的就可以了

1 const 2         maxn=410; 3 var 4         s:array[0..maxn]of longint; 5         n,m:longint; 6   7 procedure init; 8 var 9         i,x:longint;10 begin11         read(n,m);12         for i:=1 to 3*m+1 do13           begin14             read(x);15             inc(s[x]);16           end;17 end;18  19 function dfs(x:longint):boolean;20 var21         i,k:longint;22 begin23         while (s[x]=0) and (x<=n) do24           inc(x);25         if x>n then exit(true);26         k:=s[x]mod 3;27         for i:=s[x]div 3 to s[x]div 3 do28           begin29             dec(s[x+1],k);30             dec(s[x+2],k);31             if (s[x+1]>=0) and (s[x+2]>=0) then32             if dfs(x+1) then33             begin34               inc(s[x+1],k);35               inc(s[x+2],k);36               exit(true);37             end;38             inc(s[x+1],k);39             inc(s[x+2],k);40             inc(k,3);41           end;42         exit(false);43 end;44  45 procedure work;46 var47         i,j:longint;48         flag:boolean;49 begin50         flag:=false;51         for i:=1 to n do52           begin53             inc(s[i]);54             for j:=1 to n do55               if s[j]>1 then56               begin57                 dec(s[j],2);58                 if dfs(1) then59                 begin60                   inc(s[j],2);61                   if flag=false then write(i)62                   else write(' ',i);63                   flag:=true;64                   break;65                 end;66                 inc(s[j],2);67               end;68             dec(s[i]);69           end;70         if flag=false then write('NO');71 end;72  73 begin74         init;75         work;76 end.
View Code

 

转载于:https://www.cnblogs.com/Randolph87/p/3633115.html

你可能感兴趣的文章
剑指offer【书】之简历抒写
查看>>
css-a:visited
查看>>
javaScript 中创建json/转换字符串为json
查看>>
JS中for循环里面的闭包问题的原因及解决办法
查看>>
idea安装Scala插件
查看>>
mysql之查询
查看>>
Mybatis小结
查看>>
SpringData-JPA
查看>>
sqli-labs Less-11 and Less-12
查看>>
基于 Hive 的文件格式:RCFile 简介及其应用
查看>>
Windows Performance Monitor 学习笔记
查看>>
团队作业4——第一次项目冲刺 FiRsT DaY
查看>>
数组套字典排序
查看>>
【Selenium2】【HTMLTestRunner】
查看>>
一些常用的前端基础操作
查看>>
.Net remoting, Webservice,WCF,Socket区别
查看>>
ASP.NET Core Web读取appsettings.json中的配置
查看>>
HttpClient如何解决302重定向问题
查看>>
阅读阿里巴巴开发人员手册1
查看>>
macbook pro 2016 2017 15寸 雷电3 外接显卡 epu 简单教程(不修改UEFI)
查看>>