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留坑

原文地址:https://www.cnblogs.com/as3asddd/p/6083539.html