zoukankan      html  css  js  c++  java
  • Codeforces Round #423 (Div. 2)A B C D

    A. Restaurant Tables

    题意是一个点单人座有a个双人座有b个,有n组人,每组人有一个或两个人。当一个人时优先坐单人座的没有就坐没有人坐的双人座,然后才是在已经坐了一人的双人座,还没有就拒绝为他服务。当两个人时,只坐双人座的没有就拒绝服务。问这个店要拒绝服务多少人。

    直接模拟下就行了。

     1 #include <iostream>
     2 #include <string.h>
     3 #include <stdio.h>
     4 using namespace std;
     5 
     6 int main(){
     7     int n,a,b,flag = 0,num,ans= 0;
     8     cin>>n>>a>>b;
     9     for(int i = 1; i <= n; i ++){
    10         cin>>num;
    11         if(num==1){
    12             if(a>0)a--;
    13             else if(a==0){
    14                 if(b>0)b--,flag++;
    15                 else if(b==0&&flag>0)flag--;
    16                 else if(b==0&&flag==0)ans++;
    17             }
    18         }else if(num==2){
    19             if(b>0)b--;
    20             else if(b==0)ans+=2;
    21         }
    22     }
    23     cout << ans << endl;
    24     return 0;
    25 }

    B. Black Square

    题意是有n行m列,让W变成B,使的所以的B组成一个正方形,求最小的改变数,没有就输出-1,一开始我以为B会有两个以上的区域,看了别人的代码才发现不是这么一回事,

    B所在的区域最多只有一个区域,这样求下出先B的最大i,最小i,最大j,最小j,max((di-mi),(dj-mj))就是最小的正方形边长了,只要边长小于n或者m就是-1,这样就求出答案了。

    还是要多刷题多思路,加油!

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 using namespace std;
     5 int n,m,di,dj,mi=1e9,mj=1e9;
     6 char str[110][110];
     7 
     8 int main(){
     9     scanf("%d %d",&n,&m);
    10     for(int i = 0; i < n; i ++)cin>>str[i];
    11     int ans = 0;
    12     for(int i = 0; i < n; i ++){
    13         for(int j = 0; j < m; j ++){
    14             if(str[i][j]=='B'){
    15                 ans++;
    16                 di=max(di,i),mi=min(mi,i);
    17                 dj=max(dj,j),mj=min(mj,j);
    18             }
    19         }
    20     }
    21     if(!ans){
    22         puts("1");
    23         return 0;
    24     }
    25     
    26     int k = max((di-mi),(dj-mj))+1;
    27     printf("%d
    ",k>n||k>m?-1:k*k-ans);
    28     return 0;
    29 }

    C. String Reconstruction

    题意:有n个字符串,每个字符串出现了k次,每次出现的位置时是ki,求完整的字符串,要求字典最小。一开始直接暴力了,时间超限了。

    后来想想,n个字符串可以让他们分别标记为1,2,3...n,这样每输入i字符串的k次位置时,可以用数组保存下。

    当然,有些字符串出现的位置可以相同,这样可以让数组储存长度最大的那个字符串。

    输出时,可以定义一个变量p,它的作用代表已经输出了p个字符。当然,之前输入位置时要先计算下可以输出的最大字符串记为Max,

    然后定义一个i用来扫描数组,

    (一)当a[i]=0,且i>p时说明当前已经输出了p个字符,现在要输出第i个字符,由于a[i]没有被标记就直接输出字符a,因为是求字典最小的,所以就直接输出a了。

    (二)当a[i]=0,且i<=p时,说明第i个位置没有被标记,又因为i<=p,就直接扫描下一个位置了。

    (三)这个就是最重要的了。到这步就说明第i个位置已经被标记了,先取出它的值(代表了第几个字符串),然后在算下长度len,

          ①当i+len-1<=p时(-1是因为要输出len个字符的话是从i开始的)说明第i个位置代表的字符串已经被输出了,比如前面输出了abcde,现在要从第3个位置输出cd,由于之前输出了,就直接扫描下一个位置就行了,

          ②当i+len-1>p时,就输出a[i]代表的字符串从第p-i+1开始输出就行,比如前面输出了abcdef,现在要从第4个位置输出defgh,由于前面输出了def,所以现在直接输出gh就行了。

    所以用线性的时间就可以做出来了,一时头脑发热就想出来了,加油!

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <vector>
     5 using namespace std;
     6 const int MAX = 2e6+10;
     7 int a[MAX];
     8 vector<string> vs;
     9 int main(){
    10     int n,Max = 0,k,num;
    11     scanf("%d",&n);
    12     for(int i = 1; i <= n; i ++){
    13         string s;
    14         cin >> s;
    15         vs.push_back(s);
    16         scanf("%d",&k);
    17         for(int j = 1; j <= k; j ++){
    18             scanf("%d",&num);
    19             if(a[num]==0){
    20                 a[num]=i;
    21             }else if(vs[a[num]-1].length() < s.length()){
    22                 a[num] = i;
    23             }
    24             if(num+s.length()-1 > Max){
    25                 Max = num+s.length()-1;
    26             }
    27         }
    28     }
    29     int i = 1,p=0;
    30     while(i <= Max){
    31         if(a[i]==0&& i>p){
    32             printf("a");
    33             i++;p++;
    34         }else if(a[i]==0&&i<=p){
    35             i++;
    36         }else{
    37             int ans = a[i];
    38             int len = vs[ans-1].length();
    39             
    40             if(i+len-1<=p){
    41                 i++;continue;
    42             }else if(i+len-1>p){
    43                 string ss = vs[ans-1].substr(p-i+1,len);
    44                 cout << ss;    
    45                 p = i+len-1;
    46                 i++;
    47             }
    48         }
    49     }
    50     return 0;
    51 }

    D. High Load

    题意是有n个节点,其中有k个输出节点,输出节点要连接输出网络,所以可以把它看出只连接一个节点的节点,其它节点只要要连接两个节点,要求出输出节点最远的两个的最小距离,并输出所有节点的连接情况。

    想好好久也想不出,看了大牛的才发现这题是多么的简单,可以把一个节点当成最中心节点,然后在它上连接K个节点就行,一直连下去。

    下图是 n=7,k=3的情况,看了这图就应该可以秒做这到题目了。

    直接贴代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 using namespace std;
     4 
     5 int main(){
     6     int n,k;
     7     cin>>n>>k;
     8     int h = (n-1)/k;
     9     if((n-1)%k==0) printf("%d
    ",2*h);
    10     else if((n-1)%k==1)printf("%d
    ",2*h+1);
    11     else printf("%d
    ",2*h+2);
    12     for(int i = 2; i <= k+1; i ++)printf("1 %d
    ",i);
    13     for(int i = k+2; i <= n; i ++)printf("%d %d
    ",i-k,i);
    14     return 0;
    15 }
  • 相关阅读:
    【无旋转treap】模板
    线性选择算法好题
    【codeforces】305C GCD,容斥
    双连通
    线段树(3)
    线段树(2)
    线段树
    2015 Multi-University Training Contest 2
    2015 Multi-University Training Contest 1
    Codeforces Round #302 (Div. 1)
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/7155012.html
Copyright © 2011-2022 走看看