zoukankan      html  css  js  c++  java
  • Codeforces Round #503(div2) 做题记录

    前几天有点咕,马上题解会跟上~

    A.

    题意:

    有n个楼,每个楼有h层,相邻两个楼在(a,b)之间有通道

    k次询问,每次问(tA,fA)到(tB,fB)(t为楼的编号,f为楼层)的最短路

    题解:

    如果不在(a,b)层之间那先爬到离他最近的(a,b)层之间的楼层

    然后通过通道直接走,先走到tB走到对应楼层

    注意tA=tB时特判

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 int n,h,a,b,q;
     5 int main()
     6 {
     7     scanf("%d%d%d%d%d",&n,&h,&a,&b,&q);
     8     while(q--)
     9     {
    10         int t1,f1,t2,f2;
    11         int ans=0;
    12         scanf("%d%d%d%d",&t1,&f1,&t2,&f2);
    13         if(t1==t2)
    14         {
    15             printf("%d
    ",abs(f2-f1));
    16             continue;
    17         }
    18         ans+=abs(t2-t1);
    19         int now=f1;
    20         if(f1<a)ans+=abs(f1-a),now=a;
    21         else if(f1>b)ans+=abs(f1-b),now=b;
    22         ans+=abs(now-f2);
    23         printf("%d
    ",ans);
    24     }
    25     return 0;
    26 }

    B.

    题意:

    给你一个n个点的基环内向树,询问从每个点出发第一个走到的到过一次的点是什么

    题解:

    n很小,暴力模拟

     1 #include<bits/stdc++.h>
     2 #define maxn 1005
     3 using namespace std;
     4 int n;
     5 int p[maxn];
     6 bool vis[maxn];
     7 int main()
     8 {
     9     scanf("%d",&n);
    10     for(int i=1;i<=n;++i)scanf("%d",&p[i]);
    11     for(int i=1;i<=n;++i)
    12     {
    13         int u=i;
    14         memset(vis,0,sizeof(vis));
    15         while(!vis[u])vis[u]=1,u=p[u];
    16         printf("%d ",u);
    17     }
    18     return 0;
    19 }

    C.

    题意:

    有n个选民,m个党派

    你要给一些选民钱,让他们转投1号党派的票

    每个选民有一个ci和一个pi,表示让他转投的钱数和他原本投的党派

    然后要让1号党派获胜,最少要用多少钱

    题解:

    枚举其他党派的人数上限

    然后把其他党派中人数超过这个上限的强行加到1号中(当然是贪心找最小的加)

    如果不超过的另外开个数组

    最后sort一下,选最小的几个

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 #define maxn 3005
     4 using namespace std;
     5 int n,m;
     6 int p[maxn],c[maxn];
     7 vector<int> val[maxn];
     8 int num[maxn];
     9 int a[maxn],cnt;
    10 int main()
    11 {
    12     scanf("%d%d",&n,&m);
    13     for(int i=1;i<=n;++i)
    14     {
    15         scanf("%d%d",&p[i],&c[i]);
    16         val[p[i]].push_back(c[i]);
    17     }
    18     for(int i=1;i<=m;++i)sort(val[i].begin(),val[i].end());
    19     ll ans=1e15;
    20     for(int i=n;i>=0;--i)
    21     {
    22         ll res=0,tot=val[1].size();
    23         cnt=0;
    24         for(int j=2;j<=m;++j)if(val[j].size()>i)
    25         {
    26             for(int k=0;k<val[j].size()-i;++k)
    27             {
    28                 res+=val[j][k];++tot;
    29             }
    30         }
    31         for(int j=2;j<=m;++j)
    32         {
    33             int mind=val[j].size()-i;
    34             for(int k=max(mind,0);k<val[j].size();++k)
    35             {
    36                 a[++cnt]=val[j][k];
    37             }
    38         }
    39         sort(a+1,a+cnt+1);
    40         for(int j=1;j<=cnt;++j)
    41         {
    42             if(tot>i)break;
    43             tot++;res+=a[j];
    44         }
    45         ans=min(ans,res);
    46     }
    47     cout<<ans<<endl;
    48     return 0;
    49 }

    D.

    题意:

    交互题

    给你一个环,每个值和左右数值的差值是±1

    然后你不知道每个点的值

    你可以询问每个点的值,求a[i]=a[i+n/2]的位置

    题解:

    考虑60次询问,大概logn级别

    然后令f(x)=a[x]-a[x+n/2]

    这个东西在x∈[1,n/2]范围内单调

    二分一下就好了

    (比赛的时候边界写挂了导致fst QAQ)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n;
     4 int ask(int pos)
     5 {
     6     int x,y;
     7     printf("? %d
    ",pos);
     8     fflush(stdout);
     9     scanf("%d",&x);
    10     printf("? %d
    ",pos+n/2);
    11     fflush(stdout);
    12     scanf("%d",&y);
    13     return x-y;
    14 }
    15 int main()
    16 {
    17     scanf("%d",&n);
    18     if(n&1)
    19     {
    20         printf("! -1
    ");
    21         return 0;
    22     }
    23     int l=1,r=n/2;
    24     int fl=ask(l),fr=ask(r);
    25     if(fl==0)
    26     {
    27         printf("! %d
    ",l);
    28         return 0;
    29     }
    30     if(fr==0)
    31     {
    32         printf("! %d
    ",r);
    33         return 0;
    34     }
    35     if(fl>0&&fr<0)
    36     {
    37         while(l<=r)
    38         {
    39             int mid=(l+r)>>1;
    40             int t=ask(mid);
    41             if(t==0)
    42             {
    43                 printf("! %d
    ",mid);
    44                 return 0;
    45             }
    46             if(t>0)l=mid+1;else r=mid-1;
    47         }
    48     }
    49     if(fl<0&&fr>0)
    50     {
    51         while(l<=r)
    52         {
    53             int mid=(l+r)>>1;
    54             int t=ask(mid);
    55             if(t==0)
    56             {
    57                 printf("! %d
    ",mid);
    58                 return 0;
    59             }
    60             if(t>0)r=mid-1;else l=mid+1;
    61         }
    62     }
    63     puts("! -1");
    64     return 0;
    65 }

    E.

    题意:

    给你一个有向图(无自环),你需要构造一个点集Q,满足:

    x∈Q,对任意边(x,y)或(y,x),y∉Q

    x∉Q,dist(x,Q)<=2(x到Q内任意一点的距离)

    题解:

    先从前向后遍历一遍

    对于一个没有访问过的点u(vis[u]==0),把从u走一步能到达的点v标记上vis[v]=1,并把u暂时加入点集(used[u]==0)

    然后考虑反向遍历一遍,如果used[u]==1,那么把u走一步能到的点v踢出点集

     1 #include<bits/stdc++.h>
     2 #define maxn 1000005
     3 using namespace std;
     4 int n,m;
     5 vector<int> g[maxn],gg[maxn];
     6 bool vis[maxn],used[maxn];
     7 int ans[maxn];
     8 int main()
     9 {
    10     scanf("%d%d",&n,&m);
    11     for(int u,v,i=1;i<=m;++i)
    12     {
    13         scanf("%d%d",&u,&v);
    14         g[u].push_back(v);
    15         gg[v].push_back(u);
    16     }
    17     for(int u=1;u<=n;++u)if(!vis[u])
    18     {
    19         used[u]=1;
    20         for(int j=0;j<g[u].size();++j)vis[g[u][j]]=1;
    21     }
    22     int cnt=0;
    23     for(int u=n;u;--u)if(used[u])
    24     {
    25         ans[++cnt]=u;
    26         for(int j=0;j<g[u].size();++j)used[g[u][j]]=0;
    27     }
    28     printf("%d
    ",cnt);
    29     for(int i=1;i<=cnt;++i)printf("%d ",ans[i]);
    30     return 0;
    31 }
  • 相关阅读:
    p标签中的文字垂直居中
    前端调试F12
    python之hashlib
    python之__new__()
    python深浅拷贝与赋值
    【Python3之socket编程】
    5月26号 JAVA基础语法 基本运算符
    5月25号 JAVA基础语法 变量 常量 作用域
    5月22号 JAVA基础语法 数据类型
    5月22号 JAVA基础语法 标识符和关键字
  • 原文地址:https://www.cnblogs.com/uuzlove/p/9494223.html
Copyright © 2011-2022 走看看