Codeforces Round 350 div2
通过数:5
都是简单题,最后一题由于中间有点事空了一段时间,赛后没看题解只看数据过了。
A:
简单题。刚开始想用暴力写的,尽量避免分类讨论。
然后发现暴力还不如分类讨论
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(scanf("%d", &n) != EOF) {
int s1, s2;
int ans1, ans2;
ans1 = n / 7 * 2;
ans2 = n / 7 * 2;
if(n % 7 >= 6) ans1++;
if(n % 7 != 0) ans2 += min(2, n % 7);
printf("%d %d\n", ans1, ans2);
}
return 0;
}
B:
简单题。回忆一下等差数列,虽然和这题没有什么关系。枚举一下目前到哪个人就好啊。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100000 + 5;
int id[MAXN], n;
int main()
{
int k;
while(scanf("%d%d", &n, &k) != EOF) {
for(int i = 1 ; i <= n ; i++)
scanf("%d", id + i);
int mark = 1;
for(int i = 1 ; i <= n ; i++) {
if(k > i) k-= i;
else {
mark = i;
break;
}
}
printf("%d\n", id[k]);
}
return 0;
}
C:
简单题。统计。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200000 + 5;
map<int,int>id, rid;
int num[MAXN];
int b[MAXN], c[MAXN];
int n, m;
int main()
{
while(scanf("%d", &n) != EOF) {
memset(num, 0, sizeof num);
id.clear();
rid.clear();
int cnt = 0;
for(int i = 1 ; i <= n ; i++) {
int u; scanf("%d", &u);
if(id[u] == 0) id[u] = ++cnt, rid[cnt]= u;
num[id[u]]++;
}
scanf("%d", &m);
for(int i = 1 ; i <= m ; i++) scanf("%d", b + i);
for(int i = 1 ; i <= m ; i++) scanf("%d", c + i);
int s1, s2;
int ans;
s1 = 0, s2 = 0, ans = 1;
for(int i = 1 ; i <= m ; i++) {
if(num[id[b[i]]] > s1 || (num[id[b[i]]] == s1 && num[id[c[i]]] > s2)) {
s1 = num[id[b[i]]];
s2 = num[id[c[i]]];
ans = i;
}
}
printf("%d\n", ans);
}
return 0;
}
D:
刚开始想用讨论写,后来发现讨论情况过于复杂。算了算二分好像可以,就过了。
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int MAXN = 100000 + 5;
struct Node
{
int a, b;
int num;
}node[MAXN];
bool cmp(Node a, Node b){return a.num < b.num;}
int n, k;
bool check(LL v)
{
LL cnt = v;
LL temp = k;
for(int i = 1 ; i <= n ; i++) {
if(cnt * node[i].a <= node[i].b) continue;
else {
temp -= (cnt * node[i].a) - node[i].b;
}
if(temp < 0) return false;
}
return true;
}
int main()
{
while(scanf("%d%d", &n, &k) != EOF) {
for(int i = 1 ; i <= n ; i++) {
scanf("%d", &node[i].a);
}
for(int i = 1 ; i <= n ; i++) {
scanf("%d", &node[i].b);
node[i].num = node[i].b / node[i].a + (node[i].b % node[i].a == 0 ? 0 : 1);
}
sort(node + 1, node + 1 + n, cmp);
LL le = 0, re = 2e9 + 7;
while(le < re - 1) {
LL mid = (le + re) >> 1;
if(check(mid)) le = mid;
else re = mid;
// printf("le = %I64d, re = %I64d, mid = %I64d\n", le, re, mid);
}
LL ans;
if(check(re)) ans = re;
else ans = le;
printf("%I64d\n", ans);
}
return 0;
}
E:
模拟链表操作。
赛中忘记判断文件结尾一直T啊,后面加上乱调一下就过了。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 500000 + 5;
int L[MAXN], R[MAXN];
int n, m, p;
char str[MAXN], op[MAXN];
int match[MAXN];
int vis[MAXN];
stack<int>s;
int main()
{
while(scanf("%d%d%d", &n, &m, &p) != EOF) {
scanf("%s", str + 1);
scanf("%s", op);
for(int i = 1 ; i <= n ; i++) {
if(str[i] == '(') s.push(i);
else {
int u = s.top();
match[u] = i;
match[i] = u;
s.pop();
}
}
R[0] = 1, L[n + 1] = n;
for(int i = 1 ; i <= n ; i++) {
L[i] = i - 1; R[i] = i + 1;
}
memset(vis, 0, sizeof vis);
for(int i = 0 ; i < m ; i++) {
if(op[i] == 'L' && L[p] != 0) p = L[p];
else if(op[i] == 'R' && R[p] != n + 1) p = R[p];
else if(op[i] == 'D'){
int u = p, v = match[p];
if(u > v) swap(u, v);
// for(int j = u ; j <= v ; j++) vis[j] = 1;
// printf(" u = %d, v = %d\n", u, v);
int t1, t2;
t1 = L[u], t2 = R[v];
L[t2] = t1, R[t1] = t2;
p = t2;
if(p == n + 1) p = L[p];
// if(u == 1) ok1 = 0;
// if(v == n) okn = 0;
}
// printf("i = %d, p = %d\n", i, p);
}
p = R[0];
while(p < n + 1) {
printf("%c", str[p]);
p = R[p];
// printf("p = %d\n", p);
// system("pause");
}
puts("");
// for(int i = 1 ; i <= n ; i++) if(vis[i] == 0) printf("%c", str[i]);
// puts("");
}
return 0;
}
F:
暴力。
首先从小到大枚举一下长度,判断长度合法就退出。
然后注意几个坑点
1.一定存在子串放在开头比较优的情况。
2.当把一定存在子串和表示长度的字符去掉后,只剩下0字符的情况。
写的很乱,不知道有没有好一点的写法。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000000 + 5;
int cnt[20], tcnt[20];
char s[MAXN];
string ex;
bool check(int n, int len)
{
int temp = n;
int tcnt = 0;
while(temp) {
tcnt++;
temp /= 10;
}
if(len - tcnt != n) return false;
temp = n;
int ok = 1;
while(temp) {
if(cnt[temp % 10] <= 0) ok = 0;
cnt[temp % 10]--;
temp /= 10;
}
if(ok == 1) return true;
else {
temp = n;
while(temp) {
if(cnt[temp % 10] <= 0) ok = 0;
cnt[temp % 10]++;
temp /= 10;
}
return true;
}
}
int main()
{
while(scanf("%s", s) != EOF) {
cin >> ex;
memset(cnt, 0, sizeof cnt);
int len = strlen(s);
for(int i = 0 ; i < len ; i++) {
cnt[s[i] - '0']++;
}
if(cnt[0] == len) {
puts("0"); continue;
}
for(int i = 0 ; i < (int)ex.size(); i++)
cnt[ex[i] - '0']--;
int n;
for(n = 1 ; n <= len ; n++ ) {
if(check(n, len)) break;
}
memcpy(tcnt, cnt, sizeof cnt);
// printf("n = %d\n", n);
string s1, s2;
s1 = "", s2 = "";
for(int i = 1 ; i <= 9 ; i++) {
if(cnt[i]) {
// if(i == ex[0] - '0') {
// int flag = 1;
// for(int j = 0 ; j < (int)ex.size() ; j++) {
// if(ex[j] > ex[0]) {
// flag = 0;
// break;
// }
// else if(ex[j] < ex[0]) {
// break;
// }
// }
// if(flag == 0) {
//
// }
// }
// else {
s1 += i + '0';
cnt[i]--;
// }
break;
}
}
for(int i = 0 ; i <= 9 ; i++) {
if(i >= ex[0] - '0') break;
else {
while(cnt[i]) {
cnt[i]--;
s1 += i + '0';
}
}
}
int flag = 1;
for(int i = 0 ; i < (int)ex.size() ; i++) {
if(ex[i] > ex[0]) {
flag = 0;
break;
}
else if(ex[i] < ex[0]) {
break;
}
}
// printf("flag = %d\n", flag);
if(flag == 0) {
for(int i = 0 ; i <= 9 ; i++) {
if(i == ex[0] - '0') {
while(cnt[i]) {
s1 += i + '0';
cnt[i]--;
}
break;
}
}
}
s2 += ex;
for(int i = 0 ; i <= 9 ; i++) {
if(i < ex[0] - '0') continue;
else {
while(cnt[i]) {
cnt[i]--;
s2 += i + '0';
}
}
}
string ans1 = "", ans2 = "";
if(s1[0] != '0')
ans1 = s1 + s2;
else ans1 = s2 + s1;
ans2 = ex;
for(int i = 0 ; i <= 9 ; i++) {
while(tcnt[i]) {
ans2 += i + '0';
tcnt[i]--;
}
}
if(ans2[0] != '0')
cout << min(ans1, ans2) << endl;
else cout << ans1 << endl;
}
return 0;
}