Codeforces Round #380 (Div. 2)

A. Interview with Oleg

题意

将长为n的串中所有形如 ogo+Σinf]0go 的子串改写为 ,处理后输出。

要求: ogo+Σinf]0go 串需作最长匹配,即串 ogogogo 应改写为 ,而非 g oggo

分析

暴力

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;  scanf("%d",&n);
    string s,k="";  cin>>s;
    for(int i=0;i<n;i++)
    {
        if(k.size() >= 3 && k.substr(k.size()-3) == "ogo")
        {
            k = k.substr(0,k.size()-3) + "***";
            for(;(i+1)<n;i+=2)
                if(s[i] == 'g' && s[i+1] == 'o')   continue;
                else    break;
            i--;
        }
        else
            k += s[i];
    }
    if(k.size() >= 3 && k.substr(k.size()-3) == "ogo")
        k = k.substr(0,k.size()-3) + "***";
    cout<<k<<endl;
}

B. Spotlights

题意

在n*m的舞台上,每个格子当前有两种可能的状态{0:为空;1:有一个演员}。现在有一个能发射无限长的、宽度为1单位的光线的聚光灯,问有多少种摆放方案满足如下条件:

  1. 聚光灯摆放在为空的格子上
  2. 聚光灯所对的方向至少能照射到一个演员(聚光灯有ESWN四种朝向)

其中 1nm2×105

分析

  • row[i][j] 数组用于记录第 i 行前j个格子中有多少演员
  • col[i][j] 数组用于记录第 j 列前i个格子中有多少演员

此处时间复杂度 O(nm)

之后枚举每个格子的四个朝向,通过该位置到该方向端点格子的差值,判断是否存在演员

#include<bits/stdc++.h>
using namespace std;
bool mp[1010][1010];
int row[1010][1010],col[1010][1010];
int main()
{
    int n,m,ans=0;
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    {
        scanf("%d",&mp[i][j]);
        row[i][j] = row[i][j-1] + mp[i][j];
        col[i][j] = col[i-1][j] + mp[i][j];
    }
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    {
        if(mp[i][j])    continue;
        //枚举四个方向上的情况
        if(col[i][j])   ans++;
        if(row[i][j])   ans++;
        if(col[n][j] - col[i][j])   ans++;
        if(row[i][m] - row[i][j])   ans++;
    }
    printf("%d\n",ans);
}

C. Road to Cinema

Vasya is currently at a car rental service, and he wants to reach cinema. The film he has bought a ticket for starts in t minutes. There is a straight road of length s from the service to the cinema. Let’s introduce a coordinate system so that the car rental service is at the point 0, and the cinema is at the point s.

There are k gas stations along the road, and at each of them you can fill a car with any amount of fuel for free! Consider that this operation doesn’t take any time, i.e. is carried out instantly.

There are n cars in the rental service, i-th of them is characterized with two integers ci and vi — the price of this car rent and the capacity of its fuel tank in liters. It’s not allowed to fuel a car with more fuel than its tank capacity vi . All cars are completely fueled at the car rental service.

Each of the cars can be driven in one of two speed modes: normal or accelerated. In the normal mode a car covers 1 kilometer in 2 minutes, and consumes 1 liter of fuel. In the accelerated mode a car covers 1 kilometer in 1 minutes, but consumes 2 liters of fuel. The driving mode can be changed at any moment and any number of times.

Your task is to choose a car with minimum price such that Vasya can reach the cinema before the show starts, i.e. not later than in t minutes. Assume that all cars are completely fueled initially.

Input

The first line contains four positive integers n, k, s and t ( 1n2×105 , 1k2×105 , 2s109 , 1t2×109 ) — the number of cars at the car rental service, the number of gas stations along the road, the length of the road and the time in which the film starts.

Each of the next n lines contains two positive integers ci and vi ( 1ci,vi109 ) — the price of the i-th car and its fuel tank capacity.

The next line contains k distinct integers g1,g2,...,gk ( 1gis1 ) — the positions of the gas stations on the road in arbitrary order.

Output

Print the minimum rent price of an appropriate car, i.e. such car that Vasya will be able to reach the cinema before the film starts (not later than in t minutes). If there is no appropriate car, print -1.

题意

要求找出能够符合题目条件在限定时间t分钟内从0到达s位置的车辆,同时满足该车的租赁费用尽可能低。

分析

显然容易想到车辆从0到s的行驶时间与vi正相关

故二分获取最小的满足t分钟能到底目的地的 vmin

之后枚举所有可租赁的车辆,满足 vivmin 的车辆取 ci 最小的​

#include<bits/stdc++.h>
using namespace std;
const int N = 200010;
const int inf = 1e9 + 1;
struct Car {
    int c,v;
}car[N];
int g[N],n,k,s,t;
bool jud(int x) {
    int dig = 0;
    int pos = 0,dis,fast,low;
    for(int i=0;i<=k;i++) {
        dis = g[i] - pos;
        if(dis > x) return false;
        fast = min(x - dis,dis); low = dis - fast;
        dig += (fast + 2*low);
        if(dig > t) return  false;
        pos = g[i];
    }
    return true;
}
int getMin() {  //二分
    int l = 1,  r = inf, mid, fin = inf;
    while(l <= r) {
        mid = (l+r) / 2;
        if(jud(mid))    r = mid - 1,    fin = mid;
        else    l = mid + 1,    fin;
    }
    return fin;
}
int main()
{
    scanf("%d %d %d %d",&n,&k,&s,&t);
    for(int i=0;i<n;i++)
        scanf("%d %d",&car[i].c,&car[i].v);
    for(int i=0;i<k;i++)
        scanf("%d",&g[i]);
    sort(g,g+k);
    g[k] = s;
    int minV = getMin();
    int ans = inf;
    for(int i=0;i<n;i++)
        if(car[i].v >= minV && car[i].c < ans)
            ans = car[i].c;
    if(ans == inf)  printf("-1\n");
    else    printf("%d\n",ans);
}

D. Sea Battle

题意

有n个位置,共a条长为b的船,但不知道船的位置。Galya已经射击过k次,且都没有打中船。现在给长为n的字符串{0:未知;1:已经射击过}。问最少射击几次能至少射中一条船,同时给出射击方案。

分析

贪心,将a-1条船从左到右,能安排即安排在该位置。

枚举最后一条船的位置,每次射击该船可摆放位置的船尾即可。

#include<bits/stdc++.h>
using namespace std;
bool vis[200010];
vector<int> ans;
int main() {
    int n,a,b,k;    char c;
    scanf("%d %d %d %d",&n,&a,&b,&k);
    for(int i=1;i<=n;i++) {
        cin>>c;
        vis[i] = c-'0';
    }
    int pos = 1,    cnt = 0;
    for(;pos<=n && a > 1;pos++)
        if(vis[pos] == 0) 
        {
            cnt++;
            if(cnt == b)    a--,    cnt = 0;
        }
        else    cnt = 0;
    cnt = 0;
    for(;pos <= n;pos++)
        if(vis[pos] == 0)
        {
            cnt++;
            if(cnt == b)    ans.push_back(pos), cnt = 0;
        }
        else    cnt = 0;
    printf("%d\n",ans.size());
    for(int i=0;i<ans.size();i++)
    {
        if(i)   printf(" ");
        printf("%d",ans[i]);
    }
}

E. Subordinates

题意

有chief(编号s)及员工共n个人。除chief外,每个人必有其直属上司。现在每个人都报告自己的直属上司及直属上司的上司及直属上司的上司的上司 的人数。问最少多少人计算错误能够使各员工的关系成立。

分析

显然必然有1人上司数量为0,若干人上司数量为1,若干人上司数量为2

特判chief报告的上司数量是否为0,特判其余员工是否有报告为0上司的。

在处理结束后,对n的数组进行排序,依次枚举上司数量为 i 的人是否存在(i1),若某个上司数量的人不存在,则按照如下优先级确定错误的人来替补该数量的人:

  1. 非chief报告为0上司的人
  2. 报告上司数量最多的人
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int a[N];
int main()
{
    int n,s;
    scanf("%d %d",&n,&s);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    int cnt = 0;
    if(a[s] != 0)   cnt++,  a[s] = 0;
    sort(a+1,a+n+1);
    int st = 2,en = n,dig = 0;
    while(st <= en && a[st] == 0)
        dig++,  cnt++,  st++;
    for(int i=1;st <= en;i++)
        if(a[st] == i)
            while(st <= en && a[st] == i)   st++;
        else {
            if(dig) dig--;
            else    cnt++,  en--;
        }
    printf("%d\n",cnt);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值