解题思路: 如总比赛次数为3,Alice获胜一局的概率为C(1,3)(即三个里面选1个) * 1/2* 1/2*1/2。因为两者获胜概率都为1/2,则后面一直都是乘n(游戏局数)个1/2,因此只需要找到前面组合数最大的位置即可。
#includeBusing namespace std; int main() { int n; cin >> n; if (n % 2 == 0) cout << n / 2 << endl; else cout << n / 2 << ' ' << n - n / 2 << endl; return 0; }
解题思路: 当序列存在0或者序列全由和为0的两个数组成时(如1 2 4 0或-1 1 -2 2两种情况),答案是NO,否则答案是YES。判断即可。
#includeC#include using namespace std; typedef long long ll; set s; int main() { int n; ll num, ans = 0; cin >> n; for (int i = 0; i < n; i++) { cin >> num; s.insert(num); } if (s.count(0) != 0) { cout << "NO" << endl; return 0; } ans = s.size(); for (auto &i : s) { if (s.count(0 - i) != 0) ans--; } if (ans == 0) cout << "NO" << endl; else cout << "YES" << endl; return 0; }
解题思路见注释,三种方法。
1
//用vector记录前面的字符串出现的位置,输入字符串时遍历查找记录对应字符串出现位置的vector数组并加上可形成的配对数 #include#include #include #include using namespace std; typedef long long ll; unordered_map > m; //用vector记录str[i]出现的所有位置 string str[100005]; int main() { int n, k; ll ans = 0; cin >> n >> k; for (int i = 0; i < n; i++) { cin >> str[i]; while (m[str[i]].size())//对str[i]出现的所有位置进行遍历 { int num = m[str[i]].front();//取位置数组第一个位置进行判断 if (i - num > k + 1)//由于插入顺序,位置数组一定是由小到大排列 m[str[i]].erase(m[str[i]].begin());//因此间隔过大时前面的位置一定不满足题目要求,删除即可 else//当出现第一个和i间隔<=k的,说明后面的位置都满足 { ans += m[str[i]].size(); break; } } m[str[i]].push_back(i); } cout << ans << endl; return 0; }
2
//存储后二分查找 #include#include #include #include using namespace std; typedef long long ll; string str; unordered_map > m; int main() { int n, k; ll ans = 0; cin >> n >> k; for (int i = 0; i < n; i++) { cin >> str; m[str].push_back(i); } for (auto i : m) { for (int j = 0; j < i.second.size(); j++) { int l = j, r = i.second.size() - 1; while (l < r) { int mid = l + r >> 1;//当存在间距过大的位置时,二分找到第一个间距大于题目要求的位置,如2 4 6 7,对2遍历时,最后l=2(6的位置) //当数组间距都满足题目要求时,二分找到最后一个满足题目要求的位置,如3 4,对3遍历时,最后l=1(4的位置) if (i.second[mid] - i.second[j] > k + 1) r = mid; else l = mid + 1; } if (i.second[l] - i.second[j] > k + 1)//由上对二分位置的分析,需要进行判断 l--; ans += l - j; } } cout << ans << endl; return 0; }
3
//感觉有点类似滚动数组 //长度为k+2的数组遍历序列 #include#include #include using namespace std; typedef long long ll; unordered_map m; //m记录有效区间(i-k-2,i)内str的个数 string str[100005]; int main() { int n, k; ll ans = 0; cin >> n >> k; for (int i = 0; i < n; i++) { cin >> str[i]; if (i > k + 1)//当遍历完的数组长度超过k+2时,第i-k-2项前面的项和后面i项间隔一定超过题目要求,因此用--消除 m[str[i - k - 2]]--; //如i love you you love mi mixue ice cream and tea //当i=4(到第二个love处)便可以对m[i]--,意味第一个i不会和后面的i形成配对,有效区间内i的个数减1 ans += m[str[i]]; m[str[i]]++; } cout << ans << endl; return 0; }



