比赛链接:http://codeforces.com/contest/1419
A题
题意:
简单博弈论。运用数学知识分析出规律:如果总数是奇数时,最后剩下的一定是位置为奇数位置对应的值。(如果想不明白建议模拟一下过程)在这种情况下,Raze可以选择剩下哪一个,所以如果存在奇数位置存在数为奇数,Raze一定获胜,否则失败。同理,如果总数是偶数,最后剩下位置一定是偶数位置对应的值。在这种情况下,Breach可以选择剩下哪一个,所以如果存在偶数位置存在数为偶数,Breach一定获胜,否则失败。

#include <bits/stdc++.h>
using namespace std;
int main () {
int t;
cin >> t;
while(t--) {
int n;
cin >> n;
int odd = 0, even = 0;
string s;
cin >> s;
bool ok;
if(n & 1) {
ok = 0;
for(int i = 0; i < s.size(); i += 2) {
int num = s[i] - 0;
if(num & 1) {
ok = 1;
break;
}
}
}
else {
ok = 1;
for(int i = 1; i < s.size(); i += 2) {
int num = s[i] - 0;
if(!(num & 1)) {
ok = 0;
break;
}
}
}
if(ok) {
cout << "1" << endl;
}
else {
cout << "2" << endl;
}
}
}
B题
是一个数学规律寻找题。要求得到完美的图。由数学分析能力可以看出如下规律。1 3 7。。。。阶是完美的。相邻值相差为2, 2^2, 2^3.....通过这个规律先打表然后判断有多少个满足。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main () {
int t;
cin >> t;
vector<ll> biao;
ll num = 1;
ll j = 1;
for(ll i = 0; i <= 1e18; ) {
i += (num + 1) * num / 2;
num += pow(2, j);
j += 1;
biao.push_back(i);
}
// for(int i = 0; i < biao.size(); ++i) {
// cout << biao[i] << " ";
// }
// putchar(10);
while(t--) {
ll n;
cin >> n;
int ans = 0;
for(int i = 0; biao[i] <= n; ++i) {
ans++;
}
cout << ans << endl;
}
}
C题
思维题
如果全部值一样且跟目标值一样则0次;如果存在一个值与目标值一样或者正负相等则1次;其余情况两次

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main () {
int t;
cin >> t;
for(int i = 0; i < t; ++i) {
int n, x;
cin >> n >> x;
vector<int> v;
int zheng = 0;
int fu = 0;
bool sb = 0;
for(int i = 0; i < n; ++i) {
int temp;
cin >> temp;
v.push_back(temp);
if(temp > x) {
zheng += temp - x;
}
else {
fu += x - temp;
}
if(temp == x) {
sb = 1;
}
}
if(zheng == 0 && fu == 0) {
cout << 0 << endl;
}
else if(zheng == fu || sb) {
cout << 1 << endl;
}
else {
cout << 2 << endl;
}
}
}
D题

憨批题 大的插奇数位置,小的插偶数位置。数量(n-1)/2
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main () {
int n;
cin >> n;
vector<ll> v;
vector<ll> ans;
// v.resize(n);
ans.resize(n + 10);
for(int i = 0; i < n; ++i) {
ll temp;
cin >> temp;
v.push_back(temp);
}
sort(v.begin(), v.end());
// for(int i = 0; i < n; ++i) {
// cout << v[i] << " ";
// }
// cout <<endl;
int maxx = n - 1;
for(int i = 0; i < n; i += 2) {
ans[i] = v[maxx--];
}
int tt = 0;
for(int i = 1; i < n; i += 2){
ans[i] = v[tt++];
}
cout << (n - 1) / 2 << endl;
for(int i = 0; i < n; ++i) {
cout << ans[i] << " ";
}
cout << endl;
}

困难版需要注意把大的放两边。其次计数时需要O(n)遍历
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main () {
int n;
int num = 0;
cin >> n;
vector<ll> v;
vector<ll> ans;
// v.resize(n);
ans.resize(n + 10);
for(int i = 0; i < n; ++i) {
ll temp;
cin >> temp;
v.push_back(temp);
}
sort(v.begin(), v.end());
int sb = 0;
for(int i = 1; i < n; i += 2) {
ans[i] = v[sb++];
}
for(int i = 0; i < n; i += 2){
ans[i] = v[sb++];
}
for(int i = 1; i < n - 1; ++i) {
num += ans[i] < ans[i - 1] && ans[i] < ans[i + 1];
}
cout << num << endl;
for(int i = 0; i < n; ++i) {
cout << ans[i] << " ";
}
cout << endl;
}