Codeforces Round #477

1A Stairs and Elevators

读题费了半天劲。有个大楼有 n n 层,每层有 m m 个房间,总之就是个 nm n ∗ m 的表格。楼里有一些电梯和楼梯。在同一楼层走的速度是 1 1 。坐楼梯上下走的速度是每单位时间最多走 v v ,走少于 v v 也要花一单位时间。爬楼梯的速度是 1 1 。问你从一个房间到另一个房间的最短时间。

如果在同一楼层那肯定直接走就行了。

不在同一楼层,那不是直接坐电梯就是直接爬楼梯,中间换电/楼梯没有意义。那电梯的话肯定选出门左走第一个或者出门右走第一个,楼梯也是一样的道理。然后就做完了。

#include
using namespace std;
const int N=100010;
const int INF=0x3f3f3f3f;
int li[N],ei[N];
int main()
{
    int n,m,cl,ce,v;
    scanf("%d%d%d%d%d",&n,&m,&cl,&ce,&v);
    for(int i=1;i<=cl;i++)scanf("%d",li+i);li[cl+1]=m+1;
    for(int i=1;i<=ce;i++)scanf("%d",ei+i);ei[ce+1]=m+1;
    int q;
    scanf("%d",&q);
    while(q--)
    {
        int x1,y1,x2,y2,ans=INF;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        if(x1==x2){printf("%d\n",abs(y1-y2));continue;}
        int l=0,r=cl+1;
        while(l1)
        {
            int mid=(l+r)>>1;
            if(li[mid]<=y1)l=mid;
            else r=mid;
        }
        if(l)ans=min(ans,abs(y1-li[l])+abs(y2-li[l])+abs(x1-x2));
        if(r!=cl+1)ans=min(ans,abs(y1-li[r])+abs(y2-li[r])+abs(x1-x2));
        l=0,r=ce+1;
        while(l1)
        {
            int mid=(l+r)>>1;
            if(ei[mid]<=y1)l=mid;
            else r=mid;
        }
        if(l)ans=min(ans,abs(y1-ei[l])+abs(y2-ei[l])+(abs(x1-x2)+v-1)/v);
        if(r!=ce+1)ans=min(ans,abs(y1-ei[r])+abs(y2-ei[r])+(abs(x1-x2)+v-1)/v);
        printf("%d\n",ans);
    }
    return 0;
}

1B Resource Distribution

有两个service, n n 个server,第 i i 个server的性能是 ci c i ,你可以把两个service分别等分,假设性能需求为 Si S i 的service被分成了 x x 份,那么他将需要 x x 个性能不低于 Six S i x (并不下取整)的server来process,每个server只能process一个service。问用这些server能否process这两个service,能的话输出方案。

假设用到的server中性能最低的性能是 c c ,且它process的service的性能需求是 S S ,那么该service至少要被分成 Sc ⌈ S c ⌉ 份。贪心地考虑,给这个service分配性能不低于 c c 的最差的 Sc ⌈ S c ⌉ 个server,然后剩下的server就是最好的那几个了(因为假设了用到的server中的最低性能,所以不考虑更差的那些),判断这些server能否process另一个service,这个可以前缀预处理。
所以只要 O(n) O ( n ) 枚举最低性能即可。

#include
using namespace std;
const int N=300010;
const int INF=0x3f3f3f3f;
struct server
{
    int c,id;
    bool operator <(const server &t)const{return cint ok1[N],ok2[N];
int main()
{
    int n,x1,x2;
    scanf("%d%d%d",&n,&x1,&x2);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&sv[i].c);
        sv[i].id=i;
    }
    sort(sv+1,sv+n+1);
    for(int i=n;i;i--)
        if((x1+n-i)/(n-i+1)<=sv[i].c)ok1[i]=i;
        else ok1[i]=0;
    for(int i=n;i;i--)ok1[i]=max(ok1[i],ok1[i+1]);
    for(int i=n;i;i--)
        if((x2+n-i)/(n-i+1)<=sv[i].c)ok2[i]=i;
        else ok2[i]=0;
    for(int i=n;i;i--)ok2[i]=max(ok2[i],ok2[i+1]);
    for(int i=1;i<=n;i++)
    {
        int nb1=(x1+sv[i].c-1)/sv[i].c;
        if(nb11){
        if(ok2[i+nb1])
        {
            puts("Yes");
            printf("%d %d\n",nb1,n-ok2[i+nb1]+1);
            for(int j=i;jprintf("%d%c",sv[j].id,j==i+nb1-1?'\n':' ');
            for(int j=ok2[i+nb1];j<=n;j++)printf("%d%c",sv[j].id,j==n?'\n':' ');
            return 0;
        }}
        nb1=(x2+sv[i].c-1)/sv[i].c;
        if(nb11){
        if(ok1[i+nb1])
        {
            puts("Yes");
            printf("%d %d\n",n-ok1[i+nb1]+1,nb1);
            for(int j=ok1[i+nb1];j<=n;j++)printf("%d%c",sv[j].id,j==n?'\n':' ');
            for(int j=i;jprintf("%d%c",sv[j].id,j==i+nb1-1?'\n':' ');
            return 0;
        }}
    }
    return 0*puts("No");
}

1C Big Secret

已知数组 b[N] b [ N ] ,求它的一个排列,使得排列的前缀异或和递增。无解输出 “No”。

贪心。一开始前缀异或和为 0 0 ,每次选择剩余数字中能使异或和变大的最小数,若当前找不到能使异或和变大的数,就输出 “No”。

正确性待证明。

#include
using namespace std;
typedef long long ll;
const int N=100010;
ll a[N];
vector b[66];
int main()
{
    int n;
    ll tmp;
    scanf("%d",&n);
    for(int i=0;iscanf("%I64d",&tmp);
        for(int j=59;j>=0;j--)
        if(tmp>>j&1){b[j].push_back(tmp);break;}
    }
    ll res=0;
    for(int i=0;ifor(int j=0;j<60;j++)
            if(!(res>>j&1)&&!b[j].empty())
            {
                a[i]=b[j].back();
                b[j].pop_back();
                res^=a[i];
                break;
            }
        if(!a[i])return 0*puts("No");
    }
    puts("Yes");
    for(int i=0;iprintf("%I64d%c",a[i],i==n-1?'\n':' ');
    return 0;
}

1D Aztec Catacombs

待补


1E May Holidays

待补


1F May Holidays

待补


2A Mind the Gap

水题不表

#include
using namespace std;
typedef long long ll;
const int N=100010;

int main()
{
    int n,s,lst=0;
    scanf("%d%d",&n,&s);
    for(int i=0;iint h,m;
        scanf("%d%d",&h,&m);
        int now=h*60+m;
        if(lst+1+s<=now)return 0*printf("%d %d\n",lst/60,lst%60);
        lst=now+1+s;
    }
    return 0*printf("%d %d\n",lst/60,lst%60);
}

2B Watering System

水题不表

#include
using namespace std;
const int N=100010;
const int INF=0x3f3f3f3f;
int s[100010];
int main()
{
    int n,a,b;
    scanf("%d%d%d",&n,&a,&b);
    for(int i=0;iscanf("%d",s+i);
    sort(s+1,s+n);
    int sum=0;
    for(int i=0;iint cnt=0;
    for(int i=n-1;i;i--)
        if(s[0]*a/sumelse break;
    return 0*printf("%d\n",cnt);
}

你可能感兴趣的:(Codeforces)