考试T3麻将
作者:互联网
这题就是一个简单的暴力,但考试的时候不知道脑子在想什么,什么都没打出来,也许是我想的太多了。。。
这道题对于不会打麻将的人来说还是有点难理解规则的,我没说过我会打麻将,这里是题目链接。
20分思路,利用深搜来寻找答案,我们先枚举每一张听牌,那么很显然,时间复杂度就是O(n),再用深搜来判断可否胡牌。首先,我们用t[x]t[x]来表示数值为x的牌出现了多少次。那么我们就从1到n枚举对子,再枚举刻子和顺子。那么深搜的时间复杂度约是O(2n2),合起来就是O(2n^3)O(2n3)。因为9<=n<=400,所以会超时。但是不能够同时枚举多个顺子。
100分思路:
还是先枚举听牌,然后再枚举对子,接着枚举多对刻子,最后再枚举顺子。
如果我们设e数组是当前的牌的状态,那么关键代码就是:
1 e[j]%=3; 2 e[j+1]-=e[j]; 3 e[j+2]-=e[j];
那么当e[j]<0时就说明这张牌不是听牌。
下面给一组数据用于对拍:
数据输入:
9 4
1 2 3 3 4 4 5 6 8 8 9 9 9
数据输出:
2 5
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 using namespace std; 6 int n,m; 7 bool flag=1; 8 const int maxn=1e6+10; 9 int t[maxn]; 10 int e[maxn]; 11 bool check() 12 { 13 for(int i=1;i<=n;i++) 14 { 15 if(t[i]>=2) 16 { 17 bool ju=0; 18 t[i]-=2; 19 for(int j=1;j<=n+2;j++) 20 { 21 e[j]=t[j]; 22 } 23 for(int j=1;j<=n+2;j++) 24 { 25 if(e[j]<0) 26 { 27 ju=1; 28 break; 29 } 30 e[j]%=3; 31 e[j+1]-=e[j]; 32 e[j+2]-=e[j]; 33 } 34 t[i]+=2; 35 if(ju==0) 36 { 37 38 return 0; 39 } 40 } 41 } 42 return 1; 43 } 44 int main() 45 { 46 cin>>n>>m; 47 for(int i=1;i<=3*m+1;i++) 48 { 49 int x; 50 cin>>x; 51 t[x]++; 52 } 53 for(int i=1;i<=n;i++) 54 { 55 t[i]++; 56 memset(e,0,sizeof(e)); 57 if(check()==0) 58 { 59 flag=0; 60 cout<<i<<" "; 61 } 62 t[i]--; 63 } 64 if(flag==1) 65 { 66 cout<<"NO"; 67 } 68 return 0; 69 }
标签:int,T3,枚举,搜来,maxn,麻将,bool,include,考试 来源: https://www.cnblogs.com/2529102757ab/p/11122474.html