• Educational Codeforces Round 54


    这套题不难,但是场上数据水,导致有很多叉点

    A.

    因为是让求删掉一个后字典序最小,那么当a[i]>a[i+1]的时候,删掉a[i]一定最优!这个题有个叉点,当扫完一遍如果没有满足条件的,就删去最后一个字符。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <set>
     6 #include <map>
     7 #include <vector>
     8 #include <queue>
     9 #include <cmath>
    10 #include <cstdlib>
    11 #include <stack>
    12 
    13 using namespace std;
    14 const double eps = 1e-6;
    15 const int MOD=1e9+7;
    16 typedef long long LL;
    17 typedef unsigned long long ull;
    18 const int INF=2147000000;
    19 const LL inf = 1e18;
    20 LL gcd(LL a,LL b){
    21     if(!b)return a;
    22     return gcd(b,a%b);
    23 }
    24 LL lcm(LL a,LL b){
    25     return a/gcd(a,b)*b;
    26 }
    27 const int maxn=2e5+100;
    28 char s[maxn];
    29 int n;
    30 int main(){
    31     scanf("%d",&n);
    32     scanf("%s",s);
    33     int pos=-1;
    34     for(int i=0;i<n-1;i++){
    35         if(s[i+1]<s[i]){
    36             pos=i;
    37             break;
    38         }
    39     }
    40     if(pos==-1)
    41         pos=n-1;
    42     for(int i=0;i<n;i++)
    43         if(i!=pos)
    44             printf("%c",s[i]);
    45 return 0;
    46 }
    View Code

    B.

    当n是偶数的时候一定是每次都减2,也就是n/2.当n奇数的时候,就暴力减质数一直减到是偶数或者为0.注意要特判当前n是不是质数。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <set>
     6 #include <map>
     7 #include <vector>
     8 #include <queue>
     9 #include <cmath>
    10 #include <cstdlib>
    11 #include <stack>
    12 
    13 using namespace std;
    14 const double eps = 1e-6;
    15 const int MOD=1e9+7;
    16 typedef long long LL;
    17 typedef unsigned long long ull;
    18 const int INF=2147000000;
    19 const LL inf = 1e18;
    20 LL gcd(LL a,LL b){
    21     if(!b)return a;
    22     return gcd(b,a%b);
    23 }
    24 LL lcm(LL a,LL b){
    25     return a/gcd(a,b)*b;
    26 }
    27 const int maxn=2e5+100;
    28 
    29 int prime[maxn];
    30 int vis[maxn];
    31 int num;
    32 int init(int n){
    33     int m = (int)sqrt(n);
    34     vis[1]=1;
    35 
    36     for(int i = 2;i<=m;i++){
    37         for(int j =i*i; j<=n;j+=i){
    38             vis[j]=1;
    39         }
    40     }
    41     for(int i=2;i<=n;i++){
    42         if(!vis[i]){
    43             num++;
    44             prime[num] = i;
    45         }
    46     }
    47     return num;
    48 }
    49 bool judge(LL x){
    50     int m =(int)sqrt(x);
    51     for(int i=2;i<=m+1;i++){
    52         if(x%i==0)
    53             return false;
    54     }
    55     return true;
    56 }
    57 LL n;
    58 int
    59 main(){
    60     cin>>n;
    61     LL ans=0;
    62     init(2e5);
    63     if(n%2==0){
    64         cout<<n/2<<endl;
    65         return 0;
    66     }
    67     bool ok=1;
    68     while(n%2){
    69         if(judge(n)){
    70             ans+=1;
    71             ok=0;
    72             break;
    73         }
    74 
    75         int flag=0;
    76         for(int i=1;i<=num&&prime[i]<=n;i++){
    77             if(n%prime[i]==0){
    78            // printf("!!%d
    ",prime[i]);
    79                 flag=prime[i];
    80                 break;
    81             }
    82         }
    83         //printf("%d
    ",flag);
    84         if(!flag)flag=n;
    85         n-=flag;
    86         ans++;
    87     }
    88     if(ok)
    89     ans+=n/2;
    90     cout<<ans<<endl;
    91 return 0;
    92 }
    View Code

    C.

    这个题就是解一个一元二次方程,应该也可以三分来做。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <set>
     6 #include <map>
     7 #include <vector>
     8 #include <queue>
     9 #include <cmath>
    10 #include <cstdlib>
    11 #include <stack>
    12 
    13 using namespace std;
    14 const double eps = 1e-6;
    15 const int MOD=1e9+7;
    16 typedef long long LL;
    17 typedef unsigned long long ull;
    18 const int INF=2147000000;
    19 const LL inf = 1e18;
    20 LL gcd(LL a,LL b){
    21     if(!b)return a;
    22     return gcd(b,a%b);
    23 }
    24 LL lcm(LL a,LL b){
    25     return a/gcd(a,b)*b;
    26 }
    27 int main(){
    28     int T;
    29     scanf("%d",&T);
    30 
    31     int d;
    32     for(int kas=1;kas<=T;kas++){
    33         scanf("%d",&d);
    34         double del = d*d - 4*d;
    35         if(del<0){
    36             printf("N
    ");
    37         }else if(del == 0){
    38             double ans=(double)d/2;
    39 
    40             printf("Y %.9f %.9f
    ",ans,(double)(d-ans));
    41         }else{
    42             double ans1 = (double)(d+sqrt(del))/2;
    43             if(ans1<=d){
    44                 printf("Y %.9f %.9f
    ",ans1,(double)(d-ans1));
    45             }else{
    46                 double ans1 = (double)(d-sqrt(del))/2;
    47                 if(ans1<0){
    48                     printf("N
    ");
    49                 }else
    50                     printf("Y %.9f %.9f
    ",ans1,(double)(d-ans1));
    51             }
    52         }
    53     }
    54 return 0;
    55 }
    View Code

    D.

    最短路+贪心;我们先跑出最短路树来,如果k大于等于最短路树的边数,则树上的边全留下。否则的话就要删树上的边,删哪些呢?从最远(d[u]最大)的边开始删一定是最优的。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <set>
      6 #include <map>
      7 #include <vector>
      8 #include <queue>
      9 #include <cmath>
     10 #include <cstdlib>
     11 #include <stack>
     12 
     13 using namespace std;
     14 const double eps = 1e-6;
     15 const int MOD=1e9+7;
     16 typedef long long LL;
     17 typedef unsigned long long ull;
     18 const int INF=2147000000;
     19 const LL inf = 1e18;
     20 LL gcd(LL a,LL b){
     21     if(!b)return a;
     22     return gcd(b,a%b);
     23 }
     24 LL lcm(LL a,LL b){
     25     return a/gcd(a,b)*b;
     26 }
     27 const int maxn=3e5+100;
     28 int head[maxn],to[2*maxn],Next[2*maxn],w[2*maxn],id[2*maxn];
     29 struct Edge{
     30     int from,to,w,id;
     31 };
     32 vector<Edge>edges;
     33 int sz,n,m,k;
     34 void init(){
     35     sz=0;
     36     memset(head,-1,sizeof(head));
     37 }
     38 void add_edge(int a,int b,int c,int d){
     39     ++sz;
     40     to[sz]=b;
     41     w[sz]=c;
     42     id[sz]=d;
     43     Next[sz]=head[a];
     44     head[a]=sz;
     45 }
     46 struct HeapNode{
     47     int u;
     48     LL d;
     49     int from;
     50     bool operator <(const HeapNode& rhs)const{
     51         return d>rhs.d;
     52     }
     53 };
     54 int done[maxn],p[maxn];
     55 LL d[maxn];
     56 
     57 Edge edge[maxn];
     58 
     59 priority_queue<HeapNode>q;
     60 void dij(){
     61     q.push((HeapNode){1,0,-1});
     62     for(int i=0;i<=n;i++)
     63         d[i]=inf;
     64     while(!q.empty()){
     65         HeapNode x= q.top();q.pop();
     66         if(done[x.u])
     67             continue;
     68         done[x.u]=1;
     69         d[x.u] = x.d;
     70         p[x.u] = x.from;
     71         //printf("%d
    ",x.from);
     72         for(int i=head[x.u];i!=-1;i=Next[i]){
     73             int v = to[i];
     74             if(d[v]>d[x.u]+w[i]){
     75                 q.push((HeapNode){v,d[x.u]+w[i],id[i]});
     76             }
     77         }
     78     }
     79 }
     80 
     81 struct Node{
     82     int u;
     83     LL d;
     84     int from;
     85     bool operator <(const Node &rhs)const{
     86         return d<rhs.d;
     87     }
     88 };
     89 int vis[maxn];
     90 
     91 priority_queue<Node>Q;
     92 
     93 int main(){
     94     scanf("%d%d%d",&n,&m,&k);
     95 
     96     init();
     97     for(int i=1;i<=m;i++){
     98         int a,b,c;
     99         scanf("%d%d%d",&a,&b,&c);
    100         add_edge(a,b,c,i);
    101         add_edge(b,a,c,i);
    102         edge[i]=(Edge){a,b,c,i};
    103     }
    104     dij();
    105     for(int i=1;i<=n;i++){
    106         //printf("@%d
    ",p[i]);
    107         if(p[i]!=-1&& !vis[p[i]]){
    108             edges.push_back(edge[p[i]]);
    109             vis[p[i]]=1;
    110             Q.push((Node){i,d[i],p[i]});
    111            // printf("!!!%d %d %d %d
    ",edge[p[i]].from,edge[p[i]].to,edge[p[i]].w,p[i]);
    112         }
    113     }
    114     if(edges.size()<=k){
    115         printf("%d
    ",edges.size());
    116         for(int i=0;i<edges.size();i++){
    117             printf("%d ",edges[i].id);
    118         }
    119     }else{
    120         int num = edges.size();
    121         while(num>k&&!Q.empty()){
    122             Q.pop();
    123             num--;
    124         }
    125         printf("%d
    ",k);
    126         while(!Q.empty()){
    127             printf("%d ",Q.top().from);
    128             Q.pop();
    129         }
    130     }
    131 return 0;
    132 }
    View Code

    E.

    树状数组或者线段树维护一下。因为每个点的值只可能是来自于它的祖先结点,所以跑dfs的时候,进入这个点的时候更新树状数组,退栈的时候还原树状数组

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <vector>
     6 
     7 using namespace std;
     8 const int maxn=3e5+100;
     9 typedef long long LL;
    10 int head[maxn],to[2*maxn],Next[2*maxn];
    11 int n,sz,m;
    12 void add_edge(int a,int b){
    13     sz++;
    14     to[sz]=b;Next[sz]=head[a];head[a]=sz;
    15 }
    16 int lowbit(int x){
    17     return x&(-x);
    18 }
    19 LL sumv[maxn];
    20 void update(int x,int v){
    21     while(x<=n){
    22         sumv[x]+=v;
    23         x+=lowbit(x);
    24     }
    25 }
    26 LL query(int x){
    27     LL res=0;
    28     while(x){
    29         res+=sumv[x];
    30         x-=lowbit(x);
    31     }
    32     return res;
    33 }
    34 struct Node{
    35     int d,x;
    36 };
    37 vector<Node>V[maxn];
    38 int fa[maxn],dep[maxn];
    39 LL ans[maxn];
    40 
    41 void dfs(int u,int Fa,int depth){
    42     fa[u]=Fa;
    43     dep[u]=depth;
    44     for(int i=0;i<V[u].size();i++){
    45         Node N = V[u][i];
    46         update(min(N.d+depth,n),N.x);
    47     }
    48     ans[u] = query(n)-query(depth-1);
    49     for(int i=head[u];i!=-1;i=Next[i]){
    50         int v=to[i];
    51         if(v==Fa)continue;
    52         dfs(v,u,depth+1);
    53     }
    54     for(int i=0;i<V[u].size();i++){
    55         Node N = V[u][i];
    56         update(min(N.d+depth,n),-N.x);
    57     }
    58 }
    59 
    60 int main(){
    61     scanf("%d",&n);
    62     memset(head,-1,sizeof(head));
    63     for(int i=1;i<n;i++){
    64         int a,b;
    65         scanf("%d%d",&a,&b);
    66         add_edge(a,b);
    67         add_edge(b,a);
    68     }
    69     scanf("%d",&m);
    70     for(int i=1;i<=m;i++){
    71         int v,d,x;
    72         scanf("%d%d%d",&v,&d,&x);
    73         V[v].push_back((Node){d,x});
    74     }
    75     dfs(1,-1,1);
    76     for(int i=1;i<=n;i++){
    77         printf("%I64d ",ans[i]);
    78     }
    79 return 0;
    80 }
    View Code

    F.

    贪心+分类讨论。

    每一页多的为Max,少的为Min。那么一定是用少的将多的分隔开。所以如果大小关系不同则不会产生影响。否则的话,这一页我们要它最左边多出来的那块尽量长。lef=k-lastR;那么Max=Max-lef,Min=Min-1;然后我们分类讨论:

    1.ceil(Max/k)-1>Min 则return false;

    2.ceil(Max/k)<=Min

    则说明右边不会剩下。则lastR=0。

    3.ceil(Max/k)==Min-1的话,恰好被分割开,右边会有剩余,但是剩余的长度<=k,属于合法。
    lastR= Max%k ==0?k:Max%k

    这个也有叉点,要主要Min==Max的情况

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <cmath>
     6 #include <cstdlib>
     7 
     8 using namespace std;
     9 const int maxn = 3e5 + 100;
    10 int n, k;
    11 int x[maxn][2];//0 x,1 y
    12 int state,laststate,lastR;
    13 int main(){
    14     scanf("%d%d", &n, &k);
    15     for(int i = 1; i <= n; i++){
    16         scanf("%d", &x[i][0]);
    17     }
    18     for(int i = 1; i <= n; i++){
    19         scanf("%d", &x[i][1]);
    20     }
    21     bool flag = 1;
    22     for(int i = 1; i <= n; i++){ //x >= y state = 1;else state = 0;
    23         int Min = min(x[i][0], x[i][1]);
    24         int Max = max(x[i][0], x[i][1]);
    25        // printf("%d %d
    ",Min,Max);
    26         if(x[i][0] > x[i][1])
    27             state = 1;
    28         else if(x[i][0] < x[i][1])
    29             state = 0;
    30         else state = -1;
    31         if(state == laststate||laststate == -1||state == -1){
    32             int lef = k - lastR;
    33             Max = Max - lef;
    34             Min = Min - 1;
    35         }
    36         //printf("%d %d
    ",(int)ceil((double)Max/k),Min);
    37 
    38         if((int)ceil((double)Max/k)-1 > Min){
    39             flag = 0;
    40             break;
    41         }else if((int)ceil((double)Max/k) <= Min){
    42             lastR = 0;
    43         }else{
    44             lastR = Max%k == 0?k:Max%k;
    45         }
    46         laststate = state;
    47     }
    48     if(!flag){
    49         printf("NO
    ");
    50     }else{
    51         printf("YES
    ");
    52     }
    53 return 0;
    54 }
    View Code

    G.

    好像是打反转标记的线段树,留坑

  • 相关阅读:
    SRM146 DIV1 600
    SRM145 DIV1 1000
    SRM146 DIV1 300
    SRM145 DIV1 600
    【HTML打卡】0115 margin重叠、内联元素、css控制段落
    【HTML打卡】0114 盒模型margin、border、padding
    【HTML打卡】0113 div布局,css控制
    【HTML打卡】0112-html发展、doctype声明
    Machine Learning结课感想
    【ACM打卡】ZOJ 1045 2722 2830
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/9955849.html
Copyright © 2020-2023  润新知