您的位置:首页 > 其它

Codeforces Round #380 (Div. 2, Rated, Based on Technocup 2017 - Elimination Round 2)

2016-11-22 16:43 507 查看
A:题意把“ogo”是连续x(x >= 0)个“go”的子串变成“***”,输出改变后的串

先搜到“ogo”然后再判断

#include <bits/stdc++.h>

using namespace std;
const int MAXN = 200005;
const int INF = 2e9;

int main() {

char s[105];
int n;
scanf("%d%s", &n, s);
for(int i = 0; i < n;){
if(s[i] == 'o' && s[i+1] == 'g' && s[i+2] == 'o'){
i += 3;
while(s[i] == 'g' && s[i+1] == 'o'){
i += 2;
}
printf("***");
}else putchar(s[i++]);
}
return 0;
}


B:题意在一个舞台上n x m, 1代表演员,0代表空位子,你可以在一个空位子上放聚光灯,

聚光灯的放置方向有四种,问你有多少种方法,至少有一个演员在你放置聚光灯的方向上。

用四个数组分别储存前缀和,分别是从上到下,从下到上,从左到右,从右到左储存

然后枚举点,判断四个方向数组的前缀和是否大于0

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1005;
int a[MAXN][MAXN] = {};
int righ[MAXN][MAXN] = {};
int lef[MAXN][MAXN] = {};
int up[MAXN][MAXN] = {};
int down[MAXN][MAXN] = {};
int n, m;
int per(int x, int y){
int cnt = 0;
if(down[x+1][y] > 0) cnt++;
if(up[x-1][y]> 0) cnt++;
if(righ[x][y-1] > 0) cnt++;
if(lef[x][y+1] > 0) cnt++;
return cnt;
}
int main()
{

scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
scanf("%d", &a[i][j]);
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
righ[i][j] = righ[i][j-1] + a[i][j];
up[i][j] = a[i][j] + up[i-1][j];
}
}
for(int j = m; j >= 1; j--){
for(int i = n; i >= 1; i--){
lef[i][j] = lef[i][j+1] + a[i][j];
down[i][j] = down[i+1][j] + a[i][j];
}
}
int sum = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(!a[i][j]){
sum += per(i, j);
}
}
}
printf("%d\n", sum);
return 0;
}


C:你需要在t时间内走完长度为s的路,到达电影院,这条路上有k个加油站

你需要租一辆汽车,去赶到电影院, 这n辆汽车的油箱容纳量和价格也是不同,加油是不消耗时间和钱的

如果加速行驶,每1km消耗2单位的油,消耗1单位时间

如果平常速度,每1km消耗1单位的油,消耗2单位时间

问你最少需要租多少钱的汽车

二分需要消耗的汽油,找到最少需要多少油箱容纳量,然后枚举汽车,找到最低的价格

#include <bits/stdc++.h>

using namespace std;
const int MAXN = 200005;
const int INF = 2e9;
struct car{
int c, v;
}s[MAXN];
int g[MAXN];

int n, k, ss, t;

bool slove(int x){
int sum = 0;
for(int i = 1; i <= k+1; i++){
int len = g[i] - g[i-1];
if(2*len <= x){
sum += len;
}else if(len > x){
return false;
}else {
sum += (x - len) + 2*(2*len - x);
}
}
//printf(" %d %d\n", x, sum);
if(sum <= t) return true;
return false;
}

int main() {

scanf("%d%d%d%d", &n, &k, &ss, &t);
for(int i = 0; i < n; i++) scanf("%d%d", &s[i].c, &s[i].v);

for(int i = 1; i <= k; i++) scanf("%d", &g[i]);
g[0] = 0, g[k+1] = ss;
sort(g, g+k+1);
int l = 0, r = INF;
int cnt = 0;
while(l < r){
int mid = (l+r)>>1;
//printf("%d %d %d\n",mid, l, r);
cnt++;
if(slove(mid)) r = mid;
else l = mid+1;
if(cnt > 100) break;
}
//if(slove(6)) printf("SDSDS\n");
int res = INF;
for(int i = 0; i < n; i++){
if(s[i].v >= r) {
res = min(s[i].c, res);
}
}
if(res == INF) printf("-1\n");
else printf("%d\n", res);
return 0;
}


D:题意有一个1 x n 的“图”,图上有a艘长度为b的战舰,

有个人射了k发子弹没有打到战舰, 这些打到的位置标记为1,0为未知区域

问你最少射几法,射哪几个位置才能至少射中一艘战舰

先计算出每段连续的0中最多能容纳几艘战舰,设其为x, 根据鸽巢原理,最少要射x-a+1发子弹

如果你的运气差,你射了x-a次没有中,现在还有a个位置,那么随便射一发就会中

然后枚举出1的位置pos, 射pos - b(= =猜的),直到不能容纳

#include <bits/stdc++.h>

using namespace std;
const int MAXN = 200005;
int que[MAXN];
int sy[MAXN];
int main() {
int n, a, b, k;
cin >>n >>  a >> b >> k;
string s;
cin >> s;

int ans = 0;

for(int i = 0; i < n; i++){
if(s[i] == '1') que[++ans] = (i+1);
}
que[0] = 0;

que[++ans] = n+1;

int sum = 0;

for(int i = 1; i <= ans; i++){
int len = que[i] - que[i-1] - 1;
int num = len/b;
//printf("%d %d\n", len, num);
sy[i] = num;
sum += num;
}
//printf("%d\n", sum);
int res = sum - a + 1;

printf("%d\n", res);

for(int i = 1; i <= ans && res > 0; i++){
while(sy[i] > 0 && res > 0){
sy[i]--;
res--;
que[i] -= b;
printf("%d%s", que[i], (res==0)?"\n":" ");
}
}
return 0;
}


E :一个公司中,去了经理以外,每个员工都有一个直接上司,这些人都有一个属于自己的id,

给你这个公司中经理的id s, 以及这个公司每个人的上司数量,这个可能出点了错误

然后问你最少修改多少次能把它改为正常的

这个题很别扭,一句话讲不清。

大概方法就是用数组a储存上司数的数量
这个上司数必须是连续的一段 0 ~ m(m <= n-1)

也就是必须存在上司数为 0 1 2 3 4 ~ m的情况

如果有空缺必须补上,如果出现太多空缺,可以直接修改后面的

比如

8 1

0 1 1 2 3 3 7 7

你不会再补一个4、5、6吧,把两个7修改为m (m>= 1 || m <= 4)就很好了,只需要两步思路就是

枚举分割点,前部分补齐上司数a[i] = 0的情况,后部分直接修改

啰嗦这么多了

#include <bits/stdc++.h>

using namespace std;
const int MAXN = 200005;
int a[MAXN];
int main() {
int n, s, x, k = 0;
scanf("%d%d", &n, &s);
for(int i = 1; i <= n; i++) {
scanf("%d", &x);
if(i == s) {if(x) k++;}//1、如果经理的上司数不为0,当然要改
else a[x]++;
}
if(n == 1) return 0*printf("%d\n", k);

int mn = n, m = 0, c = 0;
for(int i = 1; i < n; i++){
m += a[i];
c += (a[i] == 0);
mn = min(mn, max(n-1-m, c));//把上司数 > i 改动, 把 上司数 <= i的, 都补一个
}
//printf("%d\n", mn);
printf("%d\n", mn+k);
return 0;
}


s
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐