2106. [NOIP2015] 斗地主

★★★☆   输入文件:landlords.in   输出文件:landlords.out   简单对比
时间限制:2 s  
内存限制:1025 MB

【题目描述】

牛牛最近迷上了一种叫斗地主的扑克游戏。斗地主是一种使用黑桃、红心、梅花、方片的A到K加上大小王的共54张牌来进行的扑克牌游戏。在斗地主中,牌的大小关系根据牌的数码表示如下:3<4<5<6<7<8<9<10<J<Q<K<A<2<小王<大王,而花色并不对牌的大小产生影响。每一局游戏中,一副手牌由n张牌组成。游戏者每次可以根据规定的牌型进行出牌,首先打光自己的手牌一方取得游戏的胜利。

现在,牛牛只想知道,对于自己的若干组手牌,分别最少需要多少次出牌可以将它们打光。请你帮他解决这个问题。

需要注意的是,本题中游戏者每次可以出手的牌型与一般的斗地主相似而略有不同。

具体规则如下:

【输入格式】

第一行包含用空格隔开的2个正整数Tn,表示手牌的组数以及每组手牌的张数。

接下来T组数据,每组数据n行,每行一个非负整数对aibi表示一张牌,其中ai示牌的数码,bi表示牌的花色,中间用空格隔开。特别的,我们用1来表示数码A,11表示数码J,12表示数码Q,13表示数码K;黑桃、红心、梅花、方片分别用1-4来表示;小王的表示方法为01,大王的表示方法为02。

【输出格式】

共T行,每行一个整数,表示打光第i手牌的最少次数。

【样例输入1】

  1. 1 8
  2. 7 4
  3. 8 4
  4. 9 1
  5. 10 4
  6. 11 1
  7. 5 1
  8. 1 4
  9. 1 1

【样例输出1】

  1. 3

【样例输入2】

  1. 1 17
  2. 12 3
  3. 4 3
  4. 2 3
  5. 5 4
  6. 10 2
  7. 3 3
  8. 12 2
  9. 0 1
  10. 1 3
  11. 10 1
  12. 6 2
  13. 12 1
  14. 11 3
  15. 5 2
  16. 12 4
  17. 2 2
  18. 7 2

【样例输出2】

  1. 6

【提示】

样例1说明

共有1组手牌,包含8张牌:方片7,方片8,黑桃9,方片10,黑桃J,黑桃5,方片A以及黑桃A。可以通过打单顺子(方片7,方片8,黑桃9,方片10,黑桃J),单张牌(黑桃5)以及对子牌(黑桃A以及方片A)在3次内打光。

对于不同的测试点, 我们约定手牌组数T与张数n的规模如下:

数据保证:所有的手牌都是随机生成的。

【来源】

在此键入。

这个题,,我不想多吐槽什么。。。。。。

323行,四个小时,记录...

虽然一开始就看出是暴力搜索了,,但是我写的是BFS,,从来没人AC的BFS。。

好吧我也没AC不过拿了85分。。实在是没什么好优化的了。(传说可以加贪心)

这道题的深搜,我想留到noip2017前夕写。

留个纪念

思路:

暴力枚举所有可能出现的情况

That all

代码略长,留给以后的自己,请勿吐槽

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<queue>
  6. #include<map>
  7. using namespace std;
  8. const int MAXN=;
  9. int T,n,pai_num,meiyong;
  10. int pai[MAXN];
  11. map<string,bool>mp;
  12. int js=;
  13. struct node
  14. {
  15. int a[];
  16. int step;
  17. }now,nxt;
  18. queue<node>q;
  19. int ans=0x7ffff;
  20. inline int pdvis(node p)
  21. {
  22. string gg;
  23. for(int i=;i<=;i++)
  24. gg=gg+(char)(p.a[i]-);
  25. if(mp[gg]==)return ;
  26. else
  27. {
  28. mp[gg]=;
  29. return ;
  30. }
  31. }
  32. int read(int & n)
  33. {
  34. char c=getchar();
  35. int x=,flag=;
  36. while(c<''||c>'')
  37. {if(c=='-')flag=;
  38. c=getchar();}
  39. while(c>=''&&c<='')
  40. x=x*+(c-),c=getchar();
  41. if(flag==)n= -x;
  42. else n= x;
  43. }
  44. inline void init()
  45. {
  46. mp.clear();
  47. memset(pai,,sizeof(pai));
  48. memset(now.a,,sizeof(now));
  49. memset(nxt.a,,sizeof(nxt));// 多组数据
  50. for(int i=;i<=n;i++)
  51. {
  52. read(pai_num);read(meiyong);
  53. if(pai_num==)pai_num=;// A
  54. if(pai_num==)pai_num=;//
  55. if(pai_num==)
  56. {
  57. if(meiyong==)pai_num=;// 小王
  58. else if(meiyong==)pai_num=;
  59. }
  60. pai[pai_num]++;
  61. }
  62. }
  63. inline void pd_danshun(node p)
  64. {
  65. int num=;
  66. for(int i=;i<=;i++)
  67. {
  68. if(p.a[i]>=)
  69. {
  70. num=;
  71. for(int j=i+;j<=;j++)
  72. {
  73. if(p.a[j]>=)
  74. num++;
  75. else
  76. break;
  77. }
  78. if(num>=)
  79. {
  80. for(int j=i;j<=i+num-;j++)
  81. p.a[j]--;
  82. for(int j=;j<=;j++)
  83. nxt.a[j]=p.a[j];
  84. nxt.step=p.step+;
  85. if(pdvis(nxt))
  86. q.push(nxt);
  87. for(int j=i;j<=i+num-;j++)
  88. p.a[j]++;
  89. }
  90. }
  91.  
  92. }
  93. }
  94. inline void pd_shuangshun(node p)
  95. {
  96. int num=;
  97. for(int i=;i<=;i++)
  98. {
  99. if(p.a[i]>=)
  100. {
  101. num=;
  102. for(int j=i+;j<=;j++)
  103. {
  104. if(p.a[j]>=)
  105. num++;
  106. else
  107. break;
  108. }
  109. if(num>=)
  110. {
  111. for(int j=i;j<=i+num-;j++)
  112. p.a[j]=p.a[j]-;
  113. for(int j=;j<=;j++)
  114. nxt.a[j]=p.a[j];
  115. nxt.step=p.step+;
  116. if(pdvis(nxt))
  117. q.push(nxt);
  118. for(int j=i;j<=i+num-;j++)
  119. p.a[j]=p.a[j]+;
  120. }
  121. }
  122. }
  123. }
  124. inline void pd_sanshun(node p)
  125. {
  126. int num=;
  127. for(int i=;i<=;i++)
  128. {
  129. if(p.a[i]>=)
  130. {
  131. num=;
  132. for(int j=i+;j<=;j++)
  133. {
  134. if(p.a[j]==)
  135. num++;
  136. else
  137. break;
  138. }
  139. if(num>=)
  140. {
  141. for(int j=i;j<=i+num-;j++)
  142. p.a[j]=p.a[j]-;
  143. for(int j=;j<=;j++)
  144. nxt.a[j]=p.a[j];
  145. nxt.step=p.step+;
  146. if(pdvis(nxt))
  147. q.push(nxt);
  148. for(int j=i;j<=i+num-;j++)
  149. p.a[j]=p.a[j]+;
  150. }
  151. }
  152. }
  153. }
  154. inline void pd_three(node p)
  155. {
  156. for(int i=;i<=;i++)
  157. {
  158. if(p.a[i]==)
  159. {
  160. for(int j=;j<=;j++)
  161. {
  162. if(i!=j&&(p.a[j]==||p.a[j]==))
  163. {
  164. int tmp=p.a[j];
  165. p.a[i]=;
  166. p.a[j]=;
  167. for(int k=;k<=;k++)
  168. nxt.a[k]=p.a[k];
  169. nxt.step=p.step+;
  170. if(pdvis(nxt))
  171. q.push(nxt);
  172. p.a[i]=;
  173. p.a[j]=tmp;
  174. }
  175. }
  176. p.a[i]=;
  177. for(int l=;l<=;l++)
  178. nxt.a[l]=p.a[l];
  179. nxt.step=p.step+;
  180. if(pdvis(nxt))
  181. q.push(nxt);
  182. p.a[i]=;
  183. }
  184. }
  185. }
  186. inline void pd_boom(node p)
  187. {
  188. for(int i=;i<=;i++)
  189. {
  190. if(p.a[i]==)
  191. {
  192. for(int ll=;ll<=;ll++)
  193. {
  194. for(int rr=;rr<=;rr++)
  195. {
  196. if((p.a[ll]==&&p.a[rr]==&&ll!=rr)||(p.a[ll]==&&p.a[rr]==&&ll!=rr))
  197. {
  198. int tmp=p.a[ll];
  199. p.a[i]=;
  200. p.a[ll]=;
  201. p.a[rr]=;
  202. for(int kkk=;kkk<=;kkk++)
  203. nxt.a[kkk]=p.a[kkk];
  204. nxt.step=p.step+;
  205. if(pdvis(nxt))
  206. q.push(nxt);
  207. p.a[i]=;
  208. p.a[ll]=tmp;
  209. p.a[rr]=tmp;
  210. }
  211. }
  212. }
  213. p.a[i]=;
  214. for(int l=;l<=;l++)
  215. nxt.a[l]=p.a[l];
  216. nxt.step=p.step+;
  217. if(pdvis(nxt))
  218. q.push(nxt);
  219. p.a[i]=;
  220. }
  221. }
  222. }
  223. inline void pd_other(node p)
  224. {
  225. for(int i=;i<=;i++)
  226. {
  227. if(i==)
  228. {
  229. if(p.a[i]==p.a[i+]&&p.a[i]!=)
  230. {
  231. p.a[i]=;
  232. p.a[i+]=;
  233. for(int l=;l<=;l++)
  234. nxt.a[l]=p.a[l];
  235. nxt.step=p.step+;
  236. if(pdvis(nxt))
  237. q.push(nxt);
  238. p.a[i]=;
  239. p.a[i+]=;
  240. continue;
  241. }
  242. }
  243. if(p.a[i]==||p.a[i]==)
  244. {
  245. int tmp=p.a[i];
  246. p.a[i]=;
  247. for(int l=;l<=;l++)
  248. nxt.a[l]=p.a[l];
  249. nxt.step=p.step+;
  250.  
  251. if(pdvis(nxt))
  252. q.push(nxt);
  253. p.a[i]=tmp;
  254. }
  255. }
  256.  
  257. }
  258. inline void chushihua()
  259. {
  260. for(int i=;i<=;i++)
  261. nxt.a[i]=;
  262. }
  263. inline int findans(node p)
  264. {
  265. for(int i=;i<=;i++)
  266. if(p.a[i]!=)
  267. return ;
  268. return ;
  269. }
  270. inline void gaoall(node p)
  271. {
  272. pd_boom(p);// 炸弹
  273. chushihua();// 初始化
  274. pd_danshun(p);// 单顺子
  275. pd_shuangshun(p);// 双顺子
  276. pd_sanshun(p);// 三顺子
  277. pd_three(p);// 三
  278. pd_other(p);// 单,对,大小王
  279. }
  280. void bfs()
  281. {
  282. js=;
  283. for(int i=;i<=;i++)
  284. now.a[i]=pai[i];
  285. now.step=;
  286. while(q.size()!=)
  287. q.pop();
  288. ans=0x7ffff;
  289. q.push(now);
  290. while(q.size()!=)
  291. {
  292. node p=q.front();
  293. q.pop();
  294. gaoall(p);
  295. if(findans(p)==)
  296. {
  297. ans=min(ans,p.step);
  298. js++;
  299. if(js>=)
  300. break;
  301. }
  302. }
  303. }
  304. int main()
  305. {
  306. freopen("landlords.in","r",stdin);
  307. freopen("landlords.out","w",stdout);
  308. read(T);read(n);
  309. while(T--)
  310. {
  311. init();
  312. /* for(int i=1;i<=17;i++)cout<<i<<" ";
  313. cout<<endl;
  314. for(int i=1;i<=17;i++)cout<<pai[i]<<" ";
  315. cout<<endl;*/
  316. bfs();
  317. // if(ans==2)
  318. // printf("\n%d*%d\n",T,n);
  319. printf("%d\n",ans);
  320. }
  321.  
  322. return ;
  323. }

2106. [NOIP2015] 斗地主的更多相关文章

  1. [补档][NOIP2015] 斗地主

    [NOIP2015] 斗地主 题目 传送门:http://cogs.pro/cogs/problem/problem.php?pid=2106 INPUT 第一行包含用空格隔开的2个正整数Tn,表示手 ...

  2. NOIP2015斗地主[DFS 贪心]

    题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...

  3. BZOJ 4325: NOIP2015 斗地主

    4325: NOIP2015 斗地主 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 684  Solved: 456[Submit][Status] ...

  4. NOIP2015 斗地主(搜索+剪枝)

    4325: NOIP2015 斗地主 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 270  Solved: 192[Submit][Status] ...

  5. LOJ2422 NOIP2015 斗地主 【搜索+贪心】*

    LOJ2422 NOIP2015 斗地主 LINK 题目大意很简单,就是问你斗地主的一分手牌最少多少次出完 然后我们发现对于一种手牌状态,不考虑顺子的情况是可以贪心做掉的 然后我们直接枚举一下顺子出牌 ...

  6. 【BZOJ4325】NOIP2015 斗地主 搜索+剪枝

    [BZOJ4325]NOIP2015 斗地主 Description 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗 ...

  7. NOIP2015斗地主题解 7.30考试

    问题 B: NOIP2015 斗地主 时间限制: 3 Sec  内存限制: 1024 MB 题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共 ...

  8. [NOIP2015] 斗地主(搜索)

    题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共54张牌来进行的扑克牌游戏.在斗地主中,牌的大小关系根据牌的数码表示如下:3<4< ...

  9. NOIP2015斗地主(搜索+模拟+贪心)

    %%%Luan 题面就不说了,和斗地主一样,给一组牌,求最少打几次. 注意一点,数据随机,这样我们瞎搞一搞就可以过,虽然直接贪心可以证明是错的. 枚举方法,每次搜索按照(三顺子>二顺子>普 ...

随机推荐

  1. ssh forwarding 配置

    假设有服务器A,属于某一内网,无法直接登录. A: 10.0.1.48 root/password@a 但我们有一台跳板机器可以访问该Server A B: 10.0.2.48 root/passwo ...

  2. 百万级 TCP 长连接即时通讯框架 t-io

    原文:http://www.t-io.org:9292/ https://www.oschina.net/p/t-io

  3. 初探FFT在数字图像处理中的应用(fft2函数的用法)

    初探FFT在数字图像处理中的应用 一般FFT在通信等领域都做的一维变换就能够了.可是在图像处理方面,须要做二维变换,这个时候就须要用到FFT2. 在利用Octave(或者matlab)里面的fft2( ...

  4. 【v2.x OGE-example 第三节 播放精灵动画】

    1. 位置:Drawing_example --> SpriteAnimated 2. 类名:SpriteAnimated 3.利用AnimatedSprite动画精灵类能够实现多种多种动作. ...

  5. Codeforces 690 C3. Brain Network (hard) LCA

    C3. Brain Network (hard)   Breaking news from zombie neurology! It turns out that – contrary to prev ...

  6. Bootstrap popover源码分析

    /* ======================================================================== * Bootstrap: popover.js ...

  7. VS-按F12无法跳转到函数定义,点击右键也无法跳转

    工具->选项->项目和解决方案->常规,把“在解决方案资源管理器中跟踪活动项”反选.

  8. [RK3288][Android6.0] Display驱动初始化流程小结【转】

    本文转载自:http://blog.csdn.net/kris_fei/article/details/52584903 Platform: RK3288OS: Android 6.0Kernel: ...

  9. Android Studio:Gradle project refresh failed. 解决方法

    事件 换了个电脑,Android Studio拷过来,重新配置后,打开已有的项目,报错: Gradle project refresh failed. Connection timed out: co ...

  10. PyCharm创建文件时自动添加头文件

    依次找到以下路径: File->settings->Editor->File and Code Templates->Python Script  #!/usr/bin/env ...