吉首大学第十届“新星杯”大学生程序设计大赛摸鱼记(有代码了!)
前几天在u裙看到这个比赛,发现有u盘,就报名了(
upd: 代码来了
正赛
看题
不记得做的顺序了,按题目顺序讲吧(
A
好像是个式子题,过会再搞
最后直接打了个表,oeis一波过
交了一发罚时,用了傻逼的pow T了一发(
好像吊打std了?
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int f(ll n) {
return 63 - __builtin_clzll(n);
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
ll n, ans, k;
scanf("%lld", &n);
ans = n * (n - 1) / 2;
n--;
k = floor(f(n + 2));
ans += (n + 2) * (1ll << k) - (2 * (1ll << k) * (1ll << k) + 1) / 3;
printf("%lld\n", ans);
}
return 0;
}
B
交了两发shit
发现看错题了
重新思考一波发现子集枚举就好(
发现复杂度小于\(O(2^{20}t)\)
一发A了
#include <bits/stdc++.h>
using namespace std;
int n, a[11], val[2000];
bool fl[1000];
int main() {
int t;
cin >> t;
while (t--) {
int mx = 0, cnt = 0;
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
if (n <= 1) {
cout << "0 0" << endl;
continue;
}
memset(fl, 0, sizeof(fl));
memset(val, 0, sizeof(val));
int S = (1 << n) - 1;
for (int s = 0; s <= S; s++)
for (int i = 0; i < n; i++)
if (s >> i & 1)
val[s] += a[i];
for (int s1 = 0; s1 <= S; s1++)
int s2 = S ^ s1;
for (int ss2 = s2; ss2; ss2 = (ss2 - 1) & s2)
if (val[s1] == val[ss2]) {
int x = val[s1];
if (!fl[x]) {
fl[x] = 1;
mx = max(mx, x);
cnt++;
}
}
cout << cnt << ' ' << mx << endl;
}
return 0;
}
C
简单题,满足a+b=n即可
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
cout << 1 << ' ' << n - 1 << endl;
return 0;
}
D
搞个栈记录一下当前桌面上的牌,然后搞个数组记一下每个值有没有出现过
来一张新牌的话如果存在就一直pop,然后给val加一下
如果不存在就压栈
考虑一张牌最多进栈一次,出栈一次,复杂度是线性的
#include <bits/stdc++.h>
using namespace std;
int to_int(char c) {
if (isdigit(c)) return c - '0';
else if (c == 'A') return 1;
else if (c == 'J') return 10;
else if (c == 'Q') return 11;
return 12;
}
int val1, val2;
bool appear[13];
stack<int> s;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
char c;
int rnd = 0;
while (cin >> c) {
rnd++;
int x = to_int(c);
if (!appear[x]) {
appear[x] = 1;
s.push(x);
}
else {
int y = 0, val = x;
while (y != x) {
y = s.top();
appear[y] = 0;
val += y;
s.pop();
}
if (rnd & 1)
val1 += val;
else
val2 += val;
}
}
if (val1 == val2)
cout << "-1" << endl;
else
cout << (val1 > val2 ? "zqc" : "lbg") << ' ' << max(val1, val2) << endl;
return 0;
}
E
模拟题
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
string id;
cin >> n >> id;
cout << id << ' ';
for (int i = 1; i <= n; i++) {
int t;
cin >> t;
if (!t) {
cout << 0 << ' ';
continue;
}
int x = 0, y = 0, z = 0;
x = t / 3600;
t -= x * 3600;
y = t / 60;
t -= y * 60;
z = t;
printf("%02d:%02d:%02d ", x, y, z);
}
return 0;
}
F
首先发现选出的数列一定是2~n的质数
然后考虑质数个数
如果是奇数则一定平局
否则先手必胜
这题场上没A,我把个数是2n+1时,我又分了n为奇偶讨论,然后WA了
#include <bits/stdc++.h>
#define maxn 1000005
using namespace std;
bool bpr[maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
for (int i = 2; i < maxn; i++)
bpr[i] = 1;
for (int i = 2; i < maxn; i++)
if (bpr[i])
for (int j = 2 * i; j < maxn; j += i)
bpr[j] = 0;
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int cnt = 0;
for (int i = 2; i <= n; i++)
if (bpr[i])
cnt++;
int win = 114514;
if (cnt & 1)
win = 0;
else
win = 1;
if (!win)
cout << -1 << endl;
else
cout << (win > 0 ? "cxy" : "yls") << endl;
}
return 0;
}
GH
不会
补题是不可能的,这辈子也不可能的
I
模拟题
坑有点多
#include <bits/stdc++.h>
using namespace std;
struct people {
string name;
int score[20], a, b, c, s;
void read() {
cin >> name;
s = 0;
for (int i = 1; i <= 15; i++)
cin >> score[i],
s += score[i];
a = b = c = 0;
for (int i = 1; i <= 8; i++)
a += score[i];
for (int i = 9; i <= 12; i++)
b += score[i];
for (int i = 13; i <= 15; i++)
c += score[i];
}
};
vector<people> all;
struct team {
string name;
people p[15];
int a, b, c, s, id, rank;
void read() {
cin >> name;
a = b = c = 0;
for (int i = 1; i <= 10; i++) {
p[i].read();
all.push_back(p[i]);
a += p[i].a;
b += p[i].b;
c += p[i].c;
}
s = a;
if (a >= 800)
s += b;
if (a >= 800 && b >= 400)
s += c;
}
}a[105];
bool cmp1(team a, team b) { return a.s == b.s ? a.name < b.name : a.s > b.s; }
bool cmp2(people a, people b) { return a.name < b.name; }
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;
cin >> n;
for (int i = 1; i <= n; i++)
a[i].read(),
a[i].id = i;
sort(a + 1, a + n + 1, cmp1);
for (int i = 1; i <= n; i++) {
a[i].rank = i;
if (a[i].s == a[i - 1].s)
a[i].rank = a[i - 1].rank;
}
for (int i = 1; i <= n; i++)
cout << a[i].name << ' ' << a[i].a << ' ' << a[i].b << ' ' << a[i].c << ' ' << a[i].s << ' ' << a[i].rank << endl;
int mx = 0;
sort(all.begin(), all.end(), cmp2);
for (int i = 0; i < all.size(); i++)
mx = max(mx, all[i].s);
cout << mx << ' ';
for (int i = 0; i < all.size(); i++)
if (all[i].s == mx)
cout << all[i].name << ' ';
cout << endl;
return 0;
}
J
就23一个数
手算的,不想打代码
#include <bits/stdc++.h>
using namespace std;
int main() {
cout << 1 << endl << 23 << endl;
return 0;
}
K
模拟题
每抽一次奖for一遍找最大值
复杂度O(nm)
#include <bits/stdc++.h>
#define maxn 1005
using namespace std;
int n, a[maxn], m, b[maxn], sum;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i],
sum += a[i];
cin >> m;
bool fl = 1;
while (m--) {
int x;
cin >> x;
int mx = 0;
for (int i = 1; i <= n; i++)
mx = max(mx, a[i]);
/*
(mx - x) / sum <= 1/5
5(mx - x) <= sum
*/
if (5 * (mx - a[x]) > sum) {
fl = 0;
break;
}
else {
a[x]--;
sum--;
}
}
cout << (fl ? "PASS" : "BUG") << '\n';
return 0;
}
L
sort一下,然后for一遍找最小值
#include <bits/stdc++.h>
using namespace std;
int a[25];
int main() {
int t;
cin >> t;
while (t--) {
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; i++)
cin >> a[i];
sort(a + 1, a + n + 1);
int ans = 1e9;
for (int i = 1; i <= n - k + 1; i++)
ans = min(ans, (a[i + k - 1] - a[i]) * 2);
cout << ans << endl;
}
return 0;
}
M
垃圾模拟题,写了一年(
差一点抢到一血,自闭(
#include <bits/stdc++.h>
using namespace std;
bool isn(char x) {
return x == '0' || x == '1';
}
bool check(string s) {
for (int i = 1; i < s.size(); i++)
if (s[i] == s[i - 1])
return 0;
return 1;
}
string bin(int x) {
string res = "";
bool fl = 0;
for (int i = 14; i >= 0; i--)
if (x >= (1 << i)) {
fl = 1;
x -= (1 << i);
res.push_back('1');
}
else if (fl) res.push_back('0');
return res;
}
string calc(string s) {
for (int i = 0; i < s.size(); i++) {
int j = i;
char a = s[i];
while (j + 1 < s.size() && s[j + 1] == s[i])
j++;
j++;
if (j - i == 1 || !isn(a)) continue;
string x, y, z;
x = s.substr(0, i);
y = bin(j - i);
z = s.substr(j, s.size() - j);
s = x + a + '(' + y + ')' + z;
}
for (int i = 1; i < s.size(); i++)
if (isn(s[i]) && s[i - 1] == ')') {
string x, y;
x = s.substr(0, i);
y = s.substr(i, s.size() - i);
s = x + '+' + y;
}
for (int i = 2; i < s.size(); i++)
if (s[i] == '(' && isn(s[i - 2])) {
string x, y;
x = s.substr(0, i - 1);
y = s.substr(i - 1, s.size() - (i - 1));
s = x + '+' + y;
}
return s;
}
int main() {
int t;
cin >> t;
while (t--) {
int n;
string s;
cin >> n >> s;
string ns = calc(s);
cout << (ns.size() < s.size() ? "YES" : "NO") << endl;
cout << ns << endl;
}
return 0;
}
总结
rk 17
当时最好排名是rk 12
然后F调不出来,GH不会
就一直在祈祷(
最后保住了一个16G
感觉最好发挥的话(不读错题,调出F)应该能进前9
代码太丑了,不要d我(
自闭了 /kk