2018浙江省大学生程序设计竞赛
saber保佑!
A - Peak
题意:给出一个整数序列,判断序列是否有且仅有一个峰值;
思路:
首先遍历寻找同时严格大于两边元素的值,若存在多个直接pass;
然后分别判断唯一的峰值是否前面递增,后面递减即可;
AC code:
void solve() {
int n; cin >> n;
vector<int> a(n);
for (int i = 0; i< n; i ++) cin >> a[i];
int cnt = 0;
int pos = -1;
for (int i = 1; i < n - 1; i ++) {
if (a[i] > a[i - 1] && a[i] > a[i + 1]) {
if (pos == -1) pos = i;
else {
cout << "No" << endl;
return;
}
}
}
if (pos == -1) {
cout << "No" << endl;
return;
}
for (int i = 0; i < pos; i ++) {
if (a[i] >= a[i + 1]) {
cout << "No" << endl;
return;
}
}
for (int i = pos; i < n - 1; i ++) {
if (a[i] <= a[i +1]) {
cout << "No" << endl;
return;
}
}
cout << "Yes" << endl;
}
B - King of Karaoke
题意:给出两个整数序列a和b,给序列a的每个元素+k,使得序列a等于序列b的数量最多;
思路:用序列b减去序列a,统计差值的众数即为答案;
AC code:
void solve() {
cin >> n;
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 1; i <= n; i ++) cin >> b[i];
map<int, int> mp;
int ans = 0;
for (int i = 1; i <= n; i ++) {
mp[b[i] - a[i]] ++;
ans = max(ans, mp[b[i] - a[i]]);
}
cout << ans << endl;
}
I - Magic Points
题意:有0到n-1共n个点构成的正方环型点集,每两点可以构成一条直线,构造n条直线,使得直线的交点最多;
思路:guess;
从0点开始,n条线的两端点分别为i和i+n进行构造;
但是,对于n为偶数时,最后一条线会与其他线产生的交点二次重合,非最佳情况;
所以偶数情况下最后一条线应该从n-1的点连接(3*(n-1) -1)这个点,最大话交点数;
详情可画图证明,注意,用绘图工具,防止误差;
AC code:
void solve() {
int n; cin >> n;
if (n == 2) {
cout << 0 << ' ' << 2 << ' ' << 1 << ' ' << 3 << endl;
return;
}
if (n & 1) {
cout << 0 << ' ' << n;
for (int i = 1; i < n; i ++) cout << ' ' << i << ' ' << i + n;
cout << endl;
} else {
cout << 0 << ' ' << n;
for (int i = 1; i < n - 1; i ++) cout << ' ' << i << ' ' << i + n;
cout << ' ' << n - 1 << ' ' << (3 * (n - 1)) - 1;
cout << endl;
}
}
J - CONTINUE…?
题意:
将n名学生分成四组G1G2G3G4,第i名学生的价值为i(该价值仅为题目计算描述,无实际意义,每个人都是无价的);
男生只能在G1G2组,女生只能在G3G4组;G1G3组的价值和要等于G2G4的价值和;
给出分配序列,如果不可能,输出-1;
思路:
首先如果所有人的价值和为奇数,则一定不可能成功分组;
可以证明只要是偶数就能成功分配,我们标记sum/2的价值和所在人;
然后开始遍历,被标记的人在G1G3组,否则在G2G4组,再根据男女分;
AC code:
void solve() {
int n; cin >> n;
string s; cin >> s;
s = ' ' + s;
int sum = n * (n + 1) / 2;
if (sum & 1) {
cout << "-1" << endl;
return;
}
sum /= 2;
vector<int> pos(n + 1, 0);
for (int i = n; i >= 1; i --) {
if (sum - i >= 0) {
sum -= i;
pos[i] = 1;
}
}
string ans = "";
for (int i = 1; i <= n; i ++) {
if (pos[i]) {
if (s[i] == '1') ans += '3';
else ans += '1';
} else {
if (s[i] == '1') ans += '4';
else ans += '2';
}
}
cout << ans << endl;
}
K - Mahjong Sorting
题意:略(ε=(´ο`*)))唉);
思路:大模拟,模拟方式很重要,二维拆开模拟+思路混乱WA麻了;
- 首先,将二维的麻将+点数转换为一维的:
- 牌为C,点数为x,记录为x;
- 牌为B,点数为x,记录为x+m;
- 牌为D,点数为x,记录为x+2*m;
- 如果当前手牌只有1,则所有的3*m的牌都可能为幸运牌, 优先级1;
- 现在给出的序列按照题目要求应该为一个递增序列,然后我们开始寻找是否存在空白牌:
- 不存在空白牌,则当前手牌第一张以及非手牌的3*m-n张牌都可能为幸运牌,优先级3;
- 特殊,如果当前第二张手牌不为空白牌,且第一张手牌大于第二张手牌,则说明第一张手牌必然是幸运牌,答案为1,优先级2;
- 其余的,根据空白牌的位置计算区间可能的幸运牌数即可,优先级4;
- 特判优先级很重要!!!;
AC code:
void solve() {
int n, m; cin >> n >> m;
int pos = -1;
vector<int> a;
for (int i = 0; i < n; i ++) {
char c; cin >> c;
if (c == 'W') {
pos = i;
a.push_back(-1);
continue;
}
int x; cin >> x;
if (c == 'C') a.push_back(x);
else if (c == 'B') a.push_back(x + m);
else a.push_back(x + 2 * m);
}
a.push_back(3*m+1);
if (n == 1) {
cout << 3 * m << endl;
return;
}
if (pos != 1 && a[0] >= a[1]) {
cout << 1 << endl;
return;
}
if (pos == -1) {
cout << 3 * m - n + 1 << endl;
return;
}
int ans = 0;
if (pos == 0) ans += a[1];
else if (pos == 1) ans += a[2] - a[0];
else ans += a[pos + 1] - a[pos - 1] - 1;
cout << ans << endl;
}
L - Doki Doki Literature Club
题意:给出n个字符串单词以及对于每个单词的喜爱度,选出m个单词组成喜爱度最大且字典序最小的字符串排列;
思路:pair存一下,优先喜爱度大排列,次字典序小排列,取前m个输出即可;
AC code:
bool cmp (pair<int, string> a, pair<int, string> b) {
if (a.first == b.first) return a.second < b.second;
return a.first > b.first;
}
void solve() {
int n, m; cin >> n >> m;
vector<pair<int, string>> a(n);
for (int i = 0; i < n; i ++) {
cin >> a[i].second >> a[i].first;
}
sort(a.begin(), a.end(), cmp);
vector<string> ans;
int cnt = 0;
for (int i = 0; i < m; i ++) {
auto [x, s] = a[i];
cnt += (m - i) * x;
ans.push_back(s);
}
cout << cnt << ' ';
cout << ans[0];
for (int i = 1; i < m; i ++) cout << ' ' << ans[i];
cout << endl;
}
M - Lucky 7
题意:给出长度为n的序列,是否存在元素x+b为7的倍数;
思路:根据题意跑一遍即可;
AC code:
void solve() {
int n; cin >> n;
vector<int> a(n);
int b; cin >> b;
for (int i = 0; i < n; i ++) cin >> a[i];
for (int i = 0; i < n; i ++) {
int x = a[i];
if ((x + b) % 7 == 0) {
cout << "Yes" << endl;
return;
}
}
cout << "No" << endl;
}