zoukankan      html  css  js  c++  java
  • Codeforces Round #503 Div. 2

      时间相对来说还是比较合适的,正好放假就可以打一打啦。

      A. New Building for SIS:http://codeforces.com/contest/1020/problem/A

      题意概述:有n座楼,每座楼有h层。上一层楼和下一层楼各需要一分钟,在a,b两层之间有跨楼的通道,每次可以走到相邻的楼,时间也是一分钟,给出k组询问,求每组点对之间的最小时间。

      打CF学英语。一开始看起来像是最短路,但是画画图就发现并没有那么复杂,首先两栋楼之间的那一段是无论如何都要走的,关键是a,b的限制,其实也很简单,如果楼层高的那个比a低,或者楼层低的那个比b高,就先都走到a层或b层,其他时间直接用大的减去小的就可以。还要注意一点就是如果两个点本来就在同一栋楼上就不用考虑a,b的限制可以直接走。因为这个浪费了两次提交次数...

      
     1 # include <cstdio>
     2 # include <iostream>
     3 
     4 using namespace std;
     5 
     6 int n,h,a,b,k;
     7 int ta,fa,tb,fb;
     8 int ans;
     9 
    10 int main()
    11 {
    12     scanf("%d%d%d%d%d",&n,&h,&a,&b,&k);
    13     if(a>b) swap(a,b);
    14     for (int i=1;i<=k;++i)
    15     {
    16         scanf("%d%d%d%d",&ta,&fa,&tb,&fb);
    17         ans=max(ta,tb)-min(ta,tb);
    18         if(fa>fb) swap(fa,fb);
    19         
    20         if(ta!=tb)    
    21         {
    22             if(fb<a) ans+=a-fa+a-fb;
    23             else if(fa>b) ans+=fa-b+fb-b;
    24             else ans+=fb-fa;
    25         }
    26         else ans+=fb-fa;
    27         printf("%d
    ",ans);
    28     }
    29     return 0;
    30 }
    A-New Building for SIS

      B. Badge:http://codeforces.com/contest/1020/problem/B

      题意概述:并不想概述。

      数据范围比较小,直接$N^2$模拟。

      
     1 # include <cstdio>
     2 # include <iostream>
     3 # include <cstring>
     4 
     5 using namespace std;
     6 
     7 int n,x,ans;
     8 int p[1005];
     9 bool vis[1005];
    10 
    11 int main()
    12 {
    13     scanf("%d",&n);
    14     for (int i=1;i<=n;++i)
    15         scanf("%d",&p[i]);
    16     for (int i=1;i<=n;++i)
    17     {
    18         memset(vis,0,sizeof(vis));
    19         x=i;
    20         while (1)
    21         {
    22             if(vis[x])
    23             {
    24                 ans=x;
    25                 break;
    26             }
    27             vis[x]=true;
    28             x=p[x];
    29         }
    30         printf("%d ",ans);
    31     }
    32     return 0;
    33 }
    B-Badge

      C. Elections:http://codeforces.com/contest/1020/problem/C

      题意概述:有n个学生,m个政党,每个学生有支持的政党,但是如果你给他一些钱,他就可以给你想让他投的党投票,现在想付出最少的钱使得1政党有绝对优势(票数严格大于其他党)。$1<=n,m<=3000$

      有一种贪心策略是一直收买所需钱最少的学生直到符合条件,但是这样显然是有点问题的,有可能其实只用收买一个收钱多的使得他的政党失败就可以了,但是却收买了许多所需钱虽然少但是无关紧要的人。关键是1号的票数没有确定使得难以贪心,所以考虑枚举最终票数。枚举完票数就开始处理,把每个党超过这个票数且收钱最少的人收买过来,如果这些人都收买完了可是还没有达到预定的票数,就一直收买之前还没有收买过的学生直到人数达标。开long long。

      
     1 # include <cstdio>
     2 # include <iostream>
     3 # include <cstring>
     4 # include <algorithm>
     5 
     6 using namespace std;
     7 
     8 int n,m,ns,cnt[3005],Sum[3005];
     9 struct peo
    10 {
    11     int p,c,rk;
    12 }a[3005];
    13 struct val
    14 {
    15     int rk,v;
    16 }b[3005];
    17 bool vis[3005];
    18 long long min_ans=-1,ans;
    19 
    20 bool cmpa (peo a,peo b)
    21 {
    22     if(a.p==b.p) return a.c<b.c;
    23     return a.p<b.p;
    24 }
    25 
    26 bool cmpb (val a,val b)
    27 {
    28     return a.v<b.v;
    29 }
    30 
    31 int main()
    32 {
    33     scanf("%d%d",&n,&m);
    34     for (int i=1;i<=n;++i)
    35     {
    36         scanf("%d%d",&a[i].p,&a[i].c);
    37         a[i].rk=i;
    38         b[i].rk=i;
    39         b[i].v=a[i].c;
    40     }
    41     sort(a+1,a+1+n,cmpa);
    42     sort(b+1,b+1+n,cmpb);
    43     for (int i=1;i<=n;++i)
    44         Sum[ a[i].p ]++;
    45     for (int s=1;s<=n;++s)
    46     {
    47         ns=0;
    48         ans=0;
    49         memset(vis,0,sizeof(vis));
    50         memset(cnt,0,sizeof(cnt));
    51         for (int j=1;j<=n;++j)
    52         {
    53             if(a[j].p==1) ns++,vis[ a[j].rk ]=true;
    54             else
    55             {
    56                 if(Sum[ a[j].p ]-cnt[ a[j].p ]>=s)
    57                 {
    58                     vis[ a[j].rk ]=true;
    59                     cnt[ a[j].p ]++;
    60                     ans+=a[j].c;
    61                     ns++;
    62                 }
    63             }
    64         }
    65         for (int i=1;i<=n;++i)
    66         {
    67             if(ns>=s) break;
    68             if(vis[ b[i].rk ]) continue;
    69             ns++;
    70             ans+=b[i].v;
    71         }
    72         if(min_ans==-1) min_ans=ans;
    73         min_ans=min(ans,min_ans);
    74     }
    75     cout<<min_ans;
    76     return 0;
    77 }
    C-Elections

      D. The Hat:http://codeforces.com/contest/1020/problem/D

      交互题,不会做。

      题意概述:n个人排成一个圈。发给每个人一张纸条,问有没有两个正好相对的人拿到了一样的纸条。题意清晰易懂,但是交互部分看不懂,为什么还能返回负数呢...?

      E. Sergey's problem:http://codeforces.com/contest/1020/problem/E

      题意概述:一个有向无自环图中选出一些点,使得这些点两两间没有连边,且从这些点出发可以用1或2步到达其他所有没被选到的点,有重边。

      考试的时候想了好久不会做,赛后看了其他人的代码发现此题做法很奇特,而且至今也没有明白这样做为什么能对。首先贪心的选出一些点使得没选到的点都可以走一步到达,再跑反图贪心地去掉有边相连的点。emmm所以这样怎么就对了呢...虽然找不到反例但是不是很懂,等过几天也许就有详细的题解了吧。

      
     1 # include <cstdio>
     2 # include <iostream>
     3 # define R register int
     4 
     5 using namespace std;
     6 
     7 const int maxn=1000009;
     8 int firs[maxn],x,y,n,m,h,cnt,cs[maxn],re[maxn];
     9 struct edge
    10 {
    11     int too,nex;
    12 }g[maxn];
    13 
    14 int read()
    15 {
    16     int x=0;
    17     char c=getchar();
    18     while (!isdigit(c))
    19         c=getchar();
    20     while (isdigit(c))
    21     {
    22         x=(x<<3)+(x<<1)+(c^48);
    23         c=getchar();
    24     }
    25     return x;
    26 }
    27 
    28 void write (int x)
    29 {
    30     if(x>=10) write(x/10);
    31     putchar(x%10+'0');
    32 }
    33 
    34 void add (int x,int y)
    35 {
    36     g[++h].too=y;
    37     g[h].nex=firs[x];
    38     firs[x]=h;
    39 }
    40 
    41 int main()
    42 {
    43     scanf("%d%d",&n,&m);
    44     for (R i=1;i<=m;++i)
    45     {
    46         x=read(),y=read();
    47         add(x,y);
    48     }
    49     for (R i=1;i<=n;++i)
    50         if(!re[i])
    51         {
    52             re[i]=i;
    53             for (R j=firs[i];j;j=g[j].nex)
    54                 if(!re[ g[j].too ]) re[ g[j].too ]=i;
    55             cs[i]=true;
    56         }
    57     for (R i=n;i>=1;--i)
    58         if(re[i]==i)
    59             if(cs[i])
    60             {
    61                 for (R j=firs[i];j;j=g[j].nex)
    62                     cs[ g[j].too ]=false;
    63             }
    64     for (R i=1;i<=n;++i)
    65         if(cs[i]) cnt++;
    66     printf("%d
    ",cnt);
    67     for (R i=1;i<=n;++i)
    68         if(cs[i])
    69         {
    70             write(i);
    71             putchar(' ');    
    72         }
    73     return 0;
    74 }    
    E-Sergey's problem

      ---shzr

  • 相关阅读:
    JAVA设计模式之策略模式
    Outlook邮箱配置
    Linux命令
    开发工具使用技巧
    java连接VMware虚拟机Oracle数据库问题
    C#创建带有界面交互的windows服务
    Google Galaxy Nexus刷系统
    业务逻辑?到底是什么
    发明轮子
    IBM服务器机组初始设置
  • 原文地址:https://www.cnblogs.com/shzr/p/9461951.html
Copyright © 2011-2022 走看看