• Codeforces Round #380 (div2)


    题目:http://codeforces.com/contest/738

    A 题意:给一个长度为n的字符串,如果碰到了ogo就变成***,ogo变成***,如果是ogogogo也只能变成***

     思路:暴力填充

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    char str[110],tmp[110];
    int main(){
        int len;
        while(scanf("%d",&len)!=EOF){
            for(int i=1;i<=len;i++){
                scanf(" %c",&str[i]);        
            }
            for(int i=1;i<=len;i++) tmp[i]=str[i];
            int len1=0;
            for(int i=1;i<=len;i++){
            bool flag=false;
                if(str[i]=='o'){
                    while(str[i+1]=='g'&&str[i+2]=='o'){
                        flag=true;
                        i+=2;
                    }
                    if(flag){
                        tmp[len1++]='*';
                        tmp[len1++]='*';
                        tmp[len1++]='*';
                    }
                    else tmp[len1++]=str[i];
                }
                else tmp[len1++]=str[i];
            }
            for(int i=0;i<len1;i++){
                printf("%c",tmp[i]);
            }
            printf("
    ");        
        }
        return 0;
    }
    View Code

    B.题意:给一个n*m的矩阵,有一盏灯,矩阵里面有0和1,为0的地方可以放一盏灯,灯可以上下左右四个方向照,只能直线照,问有多少种放灯的方法使得至少能照到一个1.

     思路:用树状数组维护在第i行的前缀和,和第j列的前缀和(其实直接前缀和就可以做,树状数组会多一个log),对于矩阵为0的点直接询问四个方向的和。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 const int maxn=1010;
     7 int G[maxn][maxn];
     8 int treecol[maxn][maxn];
     9 int treerow[maxn][maxn];
    10 void add(int k,int i,int m){
    11     while(i<=maxn){
    12         treecol[i][m]+=k;
    13         i+=(i&(-i));
    14     }
    15 }
    16 int query(int i,int m){
    17     int sum=0;
    18     while(i>0){
    19         sum+=treecol[i][m];
    20         i-=(i&(-i));
    21     }
    22     return sum;
    23 }
    24 void add1(int k,int i,int m){
    25     while(i<=maxn){
    26         treerow[i][m]+=k;
    27         i+=(i&(-i));
    28     }
    29 }
    30 int query1(int i,int m){
    31     int sum=0;
    32     while(i>0){
    33         sum+=treerow[i][m];
    34         i-=(i&(-i));
    35     }
    36     return sum;
    37 }
    38 int main(){
    39     int n,m;
    40     while(scanf("%d %d",&n,&m)!=EOF){
    41         memset(treerow,0,sizeof(treerow));
    42         memset(treecol,0,sizeof(treecol));
    43         for(int i=1;i<=n;i++)
    44             for(int j=1;j<=m;j++){
    45                 scanf("%d",&G[i][j]);
    46                 if(G[i][j]){
    47                     add(1,j,i);
    48                     add1(1,i,j);
    49                 }
    50             }
    51         int cnt=0;
    52         for(int i=1;i<=n;i++){
    53             for(int j=1;j<=m;j++){
    54                 if(!G[i][j]){
    55                     if(query(j,i)) cnt++;//left
    56                     if(query(m+1,i)-query(j,i)) cnt++;//right
    57                     if(query1(i,j)) cnt++;//up
    58                     if(query1(n+1,j)-query1(i,j))cnt++;//down
    59                 }
    60             }
    61         }
    62         printf("%d
    ",cnt);
    63     }
    64     return 0;
    65 }
    View Code

    C:题意:有n辆车,每辆车有邮箱大小和租金,在0的位置开始到s为终点,路上有k个加油站,到加油站可以立刻使得邮箱充满,车子如果1min走1km,那么耗油为2,如果2min走1km,那么耗油为1,求在走到终点的时间不大于t情况下所需要的最小花费

      思路:假设在0处和s处都有加油站,那么加油站把路径分成了几段,假设在s1这段时,车子以1km/min的速度走了x0  的长度,那么列一个方程(s1-x0)+2*x0=v,v是车子的邮箱容量,那么x0=v-len;那么这段所需要的时间就是x0+2*(s1-x0),就可以o(k)算出走完所需要的最短时间,然后二分油箱容量,最后选择一个满足邮箱条件价格最少的那辆车。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <cstdlib>
     6 using namespace std;
     7 int n,k,s,t;
     8 const int maxn=2e5+10;
     9 int pos[maxn];
    10 struct node {
    11     int c,v;
    12 };
    13 node car[maxn];
    14 bool cmp(node a,node b) {
    15     return a.c<b.c;
    16 }
    17 bool judge(int v) {
    18     int sum=0;
    19     for(int i=1;i<=k+1;i++) {
    20         int len=pos[i]-pos[i-1];
    21         if(len>v) return false;
    22         int x0=v-len;
    23         x0=min(len,x0);
    24         sum+=(x0+2*(len-x0));
    25     }
    26     return sum<=t;
    27 }
    28 int bin_search() {
    29     int r=1e9+1;
    30     int l=0;
    31     int ansV=1e9+1;
    32     while(l<=r) {
    33         int mid=(l+r)>>1;
    34         if(judge(mid)) {
    35             ansV=min(ansV,mid);
    36             r=mid-1;
    37         }
    38         else {
    39             l=mid+1;
    40         }
    41     }
    42     return ansV;
    43 }
    44 int main(){
    45     while(scanf("%d %d %d %d",&n,&k,&s,&t)!=EOF){
    46         for(int i=1;i<=n;i++) {
    47             scanf("%d %d",&car[i].c,&car[i].v);
    48         }
    49         pos[0]=0;
    50         pos[k+1]=s;
    51         for(int i=1;i<=k;i++) {
    52             scanf("%d",&pos[i]);
    53         }
    54         sort(pos,pos+2+k);
    55         sort(car+1,car+1+n,cmp);
    56         int V=bin_search();
    57         int ans=-1;
    58         for(int i=1;i<=n;i++) {
    59             if(car[i].v>=V) {
    60                 ans=car[i].c;
    61                 break;
    62             }
    63         }
    64         printf("%d
    ",ans);
    65     }
    66     return 0;
    67 }
    View Code

    D:题意:有一场海战,在1×n的矩形中进行,有a只船,(不会重叠),每条船的长度为b,Galya已经攻击了k次,但一条船都没有打中,并且知道这k次攻击的位置,问至少还要做多少次攻击才能打中至少一艘船,输出次数和攻击的位置

      思路:贪心,在没打中的位置以每次长度为b的递加,递加到的那个点假设要攻击记录下来,假设0的位置没打中,n+1的位置没有打中,这样就把矩形划分成了几段,处理出所有攻击的点,这个时候如果全部攻击了是能打到所有船的,那么至少一艘,我们就可以是少打(a-1)次,因为攻击的位置都是等效的,那么我们少攻击(a-1)次,必然会击中一艘船

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 int str[(int)2e5+10],n,a,b,k;
     7 int pos[(int)2e5+10];
     8 int ans[(int)2e5+10];
     9 int main(){
    10     while(scanf("%d %d %d %d",&n,&a,&b,&k)!=EOF){
    11         int tot=1;
    12         for(int i=1;i<=n;i++){
    13             scanf("%1d",&str[i]);
    14             if(str[i]) pos[tot++]=i;
    15         }
    16         pos[0]=0;
    17         pos[tot++]=n+1;
    18         int pre=1;
    19         int now=0;
    20         pre=pos[0];
    21         k+=1;
    22         tot=1;
    23         while(k--){
    24             for(int i=pre;i+b<pos[tot];i+=b){
    25                 ans[now++]=i+b;
    26             }
    27             pre=pos[tot++];
    28         }
    29         printf("%d
    ",now-a+1);
    30         for(int i=0;i<=now-a;i++){
    31             printf("%d%c",ans[i],i==now-a?'
    ':' ');
    32         }
    33     }
    34     return 0;
    35 }
    View Code

    E:题意:有n个职工其中有一个是主管,每个职工都有一个直接的上司,上司的上司也是他的上司,除了主管没有上司,现在给出每个人的上司有多少个,求最少有多少个错的

    思路:贪心 如果出了上司还有0出现的话那肯定是错的,把他设为INF,然后这个序列成立的条件是每个数都跟前面相等或者比前面少一,如果出现断了的话,从后面补,如果不能补掉,那说明后面全部都是错的。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 const int maxn=2e5+10;
     7 struct node{
     8     int id;
     9     int num;
    10 };
    11 const int INF = 0x3f3f3f3f;
    12 node a[maxn];
    13 bool cmp(const node&a,const node&b){
    14     return a.num<b.num;
    15 }
    16 int main(){
    17     int n,s;
    18     while(scanf("%d %d",&n,&s)!=EOF){
    19         int cnt=0;
    20         for(int i=1;i<=n;i++) {
    21             scanf("%d",&a[i].num);
    22             a[i].id=i;
    23             if(a[i].num==0&&i!=s){
    24                 a[i].num=INF;
    25                 //cnt++;
    26             }
    27             if(i==s&&a[i].num!=0){
    28                 a[i].num=0;
    29                 cnt++;
    30             }
    31         }
    32         sort(a+1,a+1+n,cmp);
    33         for(int i=2;i<=n;i++){
    34             if(a[i].num==a[i-1].num||a[i].num==a[i-1].num+1) continue;
    35             else {
    36                 int tmp=a[i].num-a[i-1].num-1;
    37                 if(n-i>=tmp) {
    38                     cnt+=tmp;
    39                     n-=tmp;
    40                 } else {
    41                     cnt+=(n-i);
    42                     cnt++;
    43                     break;
    44                 }
    45 
    46             }
    47         }
    48         printf("%d
    ",cnt);
    49     }
    50     return 0;
    51 }
    View Code

    F留坑

  • 相关阅读:
    APUE习题3.2用dup实现dup2以及shell中重定向符号的使用
    如何理解git checkout -- file和git reset HEAD -- file
    bash中通过设置PS1变量改变提示符颜色
    Ubuntu中root的默认密码
    Kali中装中文输入法小企鹅
    Find the Top 10 commands in your linux box!
    简明awk教程(Simple awk tutorial)
    PHP错误解决:Fatal error: Unknown: Failed opening required ...
    简单的端口扫描器(TCP connect)
    c# 爬虫(三) 文件上传
  • 原文地址:https://www.cnblogs.com/as3asddd/p/6083539.html
Copyright © 2020-2023  润新知