链接:牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ
A.小红的阶梯:

思路:
无需多言。
代码:
cpp
#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
#include<map>
#define int long long
using namespace std;
void solve() {
int a, b, c;
cin >> a >> b >> c;
if (b - a == 1 && c - b == 1) {
cout << "Yes" << endl;
return;
}
cout << "No" << endl;
return;
}
signed main() {
int t = 1;
while (t--)solve();
return 0;
}
B.小红的数组取数:

思路:
ax找最小值,by找最大值就行。
代码:
cpp
#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<map>
#include<set>
#define int long long
using namespace std;
void solve() {
int n; cin >> n;
vector<int>nums(n);
int minn = 12;
int marka = 1;
for (int i = 0; i < n; i++) {
cin >> nums[i];
if (minn > nums[i]) {
minn = nums[i];
marka = i + 1;
}
}
vector<int>numsb(n);
int maxn = 0;
int markb = 1;
for (int i = 0; i < n; i++) {
cin >> numsb[i];
if (maxn < numsb[i]) {
maxn = numsb[i];
markb = i + 1;
}
}
cout << marka << ' ' << markb << endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
solve();
return 0;
}
C.小红抽卡:

思路:
每操作x次就会恢复成原数组,先对k进行取余,假设得到的余数为s,将x-s+1到x这一段移动到最前面即可。
代码:
cpp
#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<map>
#include<set>
#define int long long
using namespace std;
void solve() {
int n, k, x;
cin >> n >> k >> x;
vector<int>nums(n + 1);
for (int i = 1; i <= n; i++) {
cin >> nums[i];
}
int s = k % (x);
map<int, int>mp;
for (int i = x - s+1; i <= x;i++) {
mp[nums[i]]++;
cout << nums[i] << ' ';
}
for (int i = 1; i <= n; i++) {
if (mp[nums[i]] != 0) {
continue;
}
cout << nums[i] << ' ';
}
cout << endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
solve();
return 0;
}
D.小红的好数对:

结论:
一个数奇数数位上的各数字之和减去偶数数位上各数字之和获得的值如果能被11整除,那么该数就能被11整除。
例如:12111:奇数数位上的数字之和为1+1+1=3,偶数数位上的数字之和为2+1=3,两数相减得0;0%11==0,所以12111能被11整除。
思路:
每输入一个数,先计算其奇数数位上的各数字之和减去偶数数位上各数字之和获得的值除以11取余,为了保证得到的cur为正整数,取余的时候要加上11,即(a-b+11)%11,该值记作cur,再判断该数的数位数量,若该数的数位数量为偶数,则在该数前面补的数也是从奇数开始的,这时候我们需要的11-cur补入,将前面统计出的11-cur的数量加入到最终答案中。若该数的数位数量为奇数,则在该数前面补的数是从偶数开始的,这时将前面统计出的cur的数量加入到最终答案中。因为两个数拼接的时候需要考虑顺序问题,所以需要最后再反向执行一遍上述操作。
代码:
cpp
#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<cmath>
#include<map>
#include<set>
#define int long long
using namespace std;
void solve() {
int n; cin >> n;
map<int, int>cnt;
int ans = 0;
vector<pair<int, int>>a(n);
for (int i = 0; i < n; i++) {
string s;
cin >> s;
reverse(s.begin(), s.end());
int cur = 0;
for (int j = 0; j < s.size(); j++) {
if (j % 2 == 0) {
cur += s[j] - '0';
}
else {
cur -= s[j] - '0';
}
}
cur = (cur%11 + 11) % 11;
if (s.size() % 2 == 0) {
ans += cnt[(11 - cur)%11];
}
else {
ans += cnt[cur];
}
cnt[cur]++;
a[i].first = cur;
a[i].second = s.size() % 2;
}
for (int i = 0; i < 11; i++) {
cnt[i] = 0;
}
reverse(a.begin(), a.end());
for (int i = 0; i < n; i++) {
int cur = a[i].first;
int jo = a[i].second;
if (jo == 0) {
ans += cnt[(11 - cur)%11];
}
if (jo == 1) {
ans += cnt[cur];
}
cnt[cur]++;
}
cout << ans << endl;
}
signed main() {
int t = 1;
while (t--)solve();
return 0;
}
E.小芳的排列构造:

思路:
L(c)+R(c)的最小值为2*n+n-1,可以通过画图看出来,可以把n放在最后一个,通过贪心从n-2到1记录拼成该数所需要的值,按从小到大的顺序放到n-1的前面,没有被记录的值放到n-1后边n之前。
代码:
cpp
#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<cmath>
#include<map>
#include<set>
#define int long long
using namespace std;
void solve(){
int n, k;
cin >> n >> k;
if (k - 2 * n - (n - 1) < 0) {
cout << -1 << endl;
return;
}
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += i;
}
if (k > sum + n) {
cout << -1 << endl;
return;
}
k -= (2 * n + n - 1);
int s = n - 2;
map<int,int>mp;
while (k>0&&s>0) {
if (k - s > 0) {
k -= s;
mp[s]++;
}
else if (k - s == 0) {
mp[s]++;
break;
}
s--;
}
for (int i = 1; i <= n-2; i++) {
if (mp[i]) {
cout << i << ' ';
}
}
if(n-1>0) cout << n-1 << ' ';
for (int i = 1; i <= n - 2; i++) {
if (!mp[i]) {
cout << i << ' ';
}
}
cout << n << ' ' << endl;
}
signed main() {
int t = 1;
while (t--)solve();
return 0;
}
F.小红的排列构造:

思路:
置换环......思路明天补。
代码:
cpp
#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
#include<numeric>
#include<map>
#include<set>
#define int long long
using namespace std;
void solve() {
int n, k; cin >> n >> k;
if (k >= n || k < (n + 1) / 2) {
cout << -1 << endl;
return;
}
vector<int>nums;
int num = 1;
nums.push_back(0);
for (int i = 1; i <= n - k - 1; i++) {
nums.push_back(num + 1);
nums.push_back(num);
num += 2;
}
for (int i = num; i < n; i++) {
nums.push_back(i+1);
}
nums.push_back(num);
for (int i = 1; i < nums.size(); i++) {
cout << nums[i] << ' ';
}
cout << endl;
}
signed main() {
int t = 1;
while (t--)solve();
return 0;
}