[关闭]
@ysner 2018-07-19T07:53:41.000000Z 字数 1376 阅读 1984

[JSOI2007]麻将

贪心


题面

张牌,范围,询问插入哪一张牌后,可以使牌由一个对子(张相同牌)、个刻子(张相同牌)或顺子(张序数连续牌)组成。

解析

首先要枚举插入的那张牌。
数据显然用桶维护。
然而我们并不好区分几张相同牌是构成刻子、对子还是顺子。
举个栗子,,一下子很有可能把它划为两个刻子,然而实际上是一刻一对一顺(构成顺子)。
由于对子只有一个,我们可以同时枚举对子。
然后从小往大枚举,能构成刻子就构,剩下的看能不能构成顺子即可。因个顺子等价于个刻子,出不了篓子。

然而作为一个逗逼,我先把所有的桶
这样会有什么后果呢?一个桶顺了解一下。
所以我们枚到当前位后才能模。

并且还要注意的是,我们要检查这两个桶是否小于
还是思维不严密的锅

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<queue>
  8. #define re register
  9. #define il inline
  10. #define ll long long
  11. #define pf(x) ((x)*(x))
  12. #define max(a,b) ((a)>(b)?(a):(b))
  13. #define min(a,b) ((a)<(b)?(a):(b))
  14. #define fp(i,a,b) for(re int i=a;i<=b;i++)
  15. #define fq(i,a,b) for(re int i=a;i>=b;i--)
  16. using namespace std;
  17. const int N=1e4+100;
  18. int n,m,a[N],tong[N],tot,p[N],sta[N],top;
  19. il ll gi()
  20. {
  21. re ll x=0,t=1;
  22. re char ch=getchar();
  23. while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
  24. if(ch=='-') t=-1,ch=getchar();
  25. while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  26. return x*t;
  27. }
  28. int main()
  29. {
  30. n=gi();m=gi();
  31. fp(i,1,3*m+1) a[i]=gi(),tong[a[i]]++;
  32. fp(i,1,n)
  33. {
  34. tong[i]++;
  35. fp(j,1,n)
  36. if(tong[j]>=2)
  37. {
  38. re int flag=1;
  39. tong[j]-=2;
  40. fp(o,1,n+2) p[o]=tong[o];
  41. fp(k,1,n+2)
  42. {
  43. if(tong[k]<0) {flag=0;break;}
  44. tong[k]%=3;tong[k+1]-=tong[k];tong[k+2]-=tong[k];
  45. }
  46. if(flag) sta[++top]=i;
  47. fp(o,1,n+2) tong[o]=p[o];
  48. tong[j]+=2;
  49. if(flag) break;
  50. }
  51. tong[i]--;
  52. }
  53. fp(i,1,top) printf("%d ",sta[i]);
  54. if(!top) puts("NO");
  55. else puts("");
  56. return 0;
  57. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注