BZOJ1028
-
题目
-
分析
n n n 的范围较小,可以暴力枚举。。
- 第一层循环枚举缺的那个和牌的数字,判断加上那个数字能否和牌。
- 第二层循环枚举对子牌,判断是否有个数大于等于 2 2 2 的数字当对子牌。若可以,判断能否组成顺子能刻子,先考虑刻子,原因是顺子牌构成需要其他牌的辅助,而其他的牌不一定存在,所以优先自己解决,这样更容易和牌。
- 第三层循环判断顺子、刻子。
时间复杂度: O ( n 3 ) O(n^3) O(n3)
-
代码
const int N = 1e4 + 5; int a[N]; int vis[N]; std::vector<int> v; int n, m; int f[N]; int solve() { for (int i = 1; i <= n; i++) { if (vis[i] >= 2) { int flag = 1; vis[i] -= 2; for (int j = 1; j <= n + 2; j ++) f[j] = vis[j]; for (int j = 1; j <= n + 2; j++) { if (f[j] < 0) {flag = 0; break;} f[j] %= 3; f[j + 1] -= f[j]; f[j + 2] -= f[j]; } vis[i] += 2; if (flag) return 1; } } return 0; } int main () { //freopen("input.in", "r", stdin); //freopen("test.out", "w", stdout); read(n); read(m); for (int i = 1; i <= 3 * m + 1; i++) read(a[i]); for (int i = 1; i <= 3 * m + 1; i++) vis[a[i]] ++; for (int i = 1; i <= n; i++) { vis[i]++; if (solve()) { v.push_back(i); } vis[i]--; } if (v.size() == 0) { cout << "NO" << endl; return 0; } for (int i = 0; i < v.size(); i++) cout << v[i] << ' '; cout << endl; return 0 ; }
-
题型
暴力