题解:
#include <iostream> #include <queue> //需要用小根堆的优先队列 #include <unordered_map> //用无序映射 using namespace std; bool pai() { int n, m; cin >> n >> m; priority_queue<int, vector<int>, greater<int>>q; //用来往里面存牌 unordered_map<int, int>arr; //记录每张牌的个数 while (n--) { int num; cin >> num; //输入当前的牌 arr[num]++; //将当前牌的数量加1 q.push(num); //往优先队列里插入该牌 } while (!q.empty()) //根据队列里面个数去循环(只要队列不为空就循环) { int number = q.top(); //将队列的堆顶元素(最小值)记录下来 q.pop(); //必须得先弹出再去判断这个牌的数量 if (arr[number] == 0) continue; //如果当前牌的个数为0,则开始下一次循环 for (int i = 0; i < m; i++) //根据每组顺子的长度去循环 { int cnt = arr[number+i]--; //用cnt记录当前牌的个数,记录后,就让当前牌个数-1,因为当前牌构成了顺子,且索引是number+i,因为只有连着的才能构成顺子 if (cnt == 0) return false; //如果要构成顺子的该牌数量为0,则表示无法构成顺子,返回false } } return true; //若能顺利构成若干组m长度的顺子,则返回true } int main() { int t; cin >> t; while (t--) { if (pai()) cout << "YES" << endl; else cout << "NO" << endl; } }
以前写的代码:
#include <bits/stdc++.h> using namespace std; int main() { int t; cin >> t; //有几副牌 vector<int>arr; //定义的数组来放牌 while (t--) //根据t是多少来循环几次 { int n, m; cin >> n >> m; //输入1副牌的数量以及顺子长度 arr.resize(n); for (int i = 0; i < n; i++) cin >> arr[i]; sort(arr.begin(), arr.end(), less<int>()); //将牌从小到大排序 int min = 0; //顺子最开始的那个牌 int flag = 0; //去判断有没有找到顺子的头 int count = 0; //去计算该顺子的目前长度 int zushu = 0; //有几组顺子 bool zuizhonflag = 1; //去判断最终能否符合题中条件,即若干组m长度的顺子 if (n % m == 0) { zushu = n / m; //来记录顺子有几组 } else //如果不能组成若干组长度为m的顺子则直接终止,看下一副牌 { cout << "No" << endl; continue; } while (zushu--) //有几组顺子就循环几次 { zuizhonflag = 1; //先假设符合题意,能组成若干组长度为m的顺子 count = 0; //将目前顺子长度定义为0 flag = 0; //0表示还没有找到顺子的头 for (int i = 0; i < n; i++) //遍历该副牌 { if (arr[i] != 0 && flag == 0) //若flag=0,且找到第一个不是0的牌,则该牌为顺子的头,用min记录 { min = arr[i]; arr[i] = 0; //将该牌删去,记录为0 flag = 1; //1表示找到顺子的头了 count++; //顺子长度加1 } if (flag == 1 && arr[i] == min + 1) //若存在顺子的头,且该牌是顺子中的下一个牌(比如,顺子头是2,则要找3) { min = arr[i]; //则将min记录为arr[i](找到3后,把min记录为3,方便去找4) arr[i] = 0; //将该牌删去 count++; //顺子长度加1 } if (count == m) break; //若顺子长度到了所规定的m长,则跳出for循环,开始找下一组顺子 } if (count != m) //若遍历完for循环,发现顺子长度不够,则该副牌不符合题意 { zuizhonflag = 0; cout << "No" << endl; //输出No,跳出while循环,开始下一副牌 break; } } if (zuizhonflag == 1) //若该副牌符合题意,则输出YES,并清空vector容器 { cout << "Yes" << endl; } arr.clear(); //清空容器 } return 0; }
参考(来自学长们题解):
资料:
c++ unordered_map和map的区别-CSDN博客
C++ map与unordered_map区别及使用_c++中的map和unordered_map的区别和使用场景-CSDN博客