遇到这种题,再看看这数据范围,一般都是暴力。
然而暴力也是有差别的,比如我写的那个,代码悠长有让人看不懂,而且最终还没过,看了点题解的思路,发现我有很多情况都重复了,导致不仅时间复杂度无法保证,而且正确性还待考察。
首先,我们从1到n枚举等待牌,然后在枚举对子,接着在枚举刻子,最后看看能否凑成顺子。为啥先看刻子再看顺子咧,因为三张相同的顺子就是三张刻子,而且对于一种牌,刻子取完后剩下的牌一定用来构成顺子,减少了枚举情况。
具体的做法就是开一个类似桶的数组,记录每种数字牌有多少个,然后枚举刻子的时候就是num[i] % 3,若还剩下,那么一定用来构成顺子,然后判断这张牌一下能否构成顺子,不能就说明当前枚举的等待牌不对。
刚开始我是这么想的,记录顺子和刻子个数,然后看最后是和否等于m,其实没必要,因为只有14张牌,除了对子剩下的牌都用来构成顺子或刻子,所以如果哪一张牌构不成顺子或刻子,就说明这套牌不能和。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<stack> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const db eps =1e-8; 19 const int maxn = 3e3 + 5; 20 inline ll read() 21 { 22 ll ans = 0; 23 char ch = getchar(), last = ' '; 24 while(!isdigit(ch)) {last = ch; ch = getchar();} 25 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 26 if(last == '-') ans = -ans; 27 return ans; 28 } 29 inline void write(ll x) 30 { 31 if(x < 0) putchar('-'), x = -x; 32 if(x >= 10) write(x / 10); 33 putchar(x % 10 + '0'); 34 } 35 36 int n, m, N, a[maxn]; 37 int num[maxn], ntp[maxn]; 38 39 bool judge() 40 { 41 for(int i = 1; i <= n; ++i) 42 { 43 ntp[i] %= 3; 44 if(ntp[i]) 45 { 46 if(i + 2 > n) return 0; 47 for(int j = i + 1; j <= i + 2; ++j) 48 { 49 ntp[j] -= ntp[i]; 50 if(ntp[j] < 0) return 0; 51 } 52 // if(--ntp[i + 1] < 0) return 0; //刚开始这么写的,但可能剩下的有两张牌,都得用来构成顺子 53 // if(--ntp[i + 2] < 0) return 0; 54 } 55 } 56 return 1; 57 } 58 59 int main() 60 { 61 n = read(); m = read(); 62 for(int i = 1; i <= 3 * m + 1; ++i) {int x = read(); num[x]++;} 63 bool flag = false; 64 for(int i = 1; i <= n; ++i) 65 { 66 num[i]++; 67 for(int j = 1; j <= n; ++j) //枚举对子 68 { 69 for(int k = 1; k <= n; ++k) ntp[k] = num[k]; 70 ntp[j] -= 2; if(ntp[j] < 0) continue; 71 if(judge()) {flag = 1; write(i); space; break;} 72 } 73 num[i]--; 74 } 75 if(!flag) printf("NO "); 76 return 0; 77 }