zoukankan      html  css  js  c++  java
  • Codeforces#363 Div2

    A题:

    题意:给定一些数,给定一些往左走和往右走的操作,问是否能够相遇,如果相遇请求出相遇时间

    分析:对于相邻两个数,如果大的往左,小的往右就能够相遇,否则不能相遇,在求出所有相遇当中的第一次相遇即可

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #include <vector>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <bitset>
    10 #include <cmath>
    11 #include <queue>
    12 #include <stack>
    13 using namespace std;
    14 const int maxn=200050;
    15 const int INF=1<<30;
    16 int a[maxn];
    17 int n;
    18 int main()
    19 {
    20     while(cin>>n)
    21     {
    22         string s;
    23         cin>>s;
    24         for(int i=0;i<n;i++)
    25             cin>>a[i];
    26         int flag=0;
    27         int k;
    28         int minx=INF;
    29         for(int i=0;i<n-1;i++)
    30         {
    31             int flag1=0;
    32             if(s[i]=='R'&&s[i+1]=='L'&&a[i]<a[i+1])
    33             {
    34                 flag=1;  flag1=1;
    35             }
    36             else if(s[i]=='L'&&s[i+1]=='R'&&a[i]>a[i+1]){
    37                 flag=1; flag1=1;
    38             }
    39             if(flag1){
    40                 int maxt=max(a[i],a[i+1]);
    41                 int mint=min(a[i],a[i+1]);
    42                 int t=(maxt-mint)/2;
    43                 if(t<minx)
    44                     minx=t;
    45             }
    46         }
    47         if(flag) {
    48             cout<<minx<<endl;
    49         }else
    50         {
    51             cout<<"-1"<<endl;
    52         }
    53     }
    54     return 0;
    55 }
    View Code

    B题:

    题意:*代表墙,.代表空地,一个炸弹能够炸掉横竖各一列的墙,问能否通过一枚炸弹,让所有全部变成平地

    分析:这是一道Hack点极多的题,我就因为这题被Hack了,Ranting一朝回到解放前。直接模拟即可,但是要注意两种情况,一个是没有一个格子是墙壁的情况,还有一种选择放置炸弹的点不是墙壁的情况

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #include <vector>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <bitset>
    10 #include <cmath>
    11 #include <queue>
    12 #include <stack>
    13 using namespace std;
    14 const int maxn=1100;
    15 int n,m;
    16 int vis[maxn],d[maxn];
    17 int main()
    18 {
    19     while(cin>>n>>m)
    20     {
    21         char s[maxn][maxn];
    22         for(int i=0;i<n;i++)
    23             cin>>s[i];
    24         int flag1=0;
    25         for(int i=0;i<n;i++){
    26             for(int j=0;j<m;j++){
    27                 if(s[i][j]=='*'){
    28                     flag1=1; break;
    29                 }
    30             }
    31         }
    32         if(!flag1){
    33             cout<<"YES"<<endl;
    34             cout<<"1"<<" "<<"1"<<endl;
    35             continue;
    36         }
    37         memset(vis,0,sizeof(vis));
    38         memset(d,0,sizeof(d));
    39         int flag=0;
    40         int cnt=0;
    41         for(int i=0;i<n;i++)
    42         {
    43             for(int j=0;j<m;j++){
    44                 if(s[i][j]=='*'){
    45                     vis[i]++;
    46                     d[j]++;
    47                     cnt++;
    48                 }
    49             }
    50         }
    51         int h,k;
    52         for(int i=0;i<n;i++){
    53             for(int j=0;j<m;j++){
    54                 if(s[i][j]=='*'){
    55                     if(vis[i]+d[j]==cnt+1){
    56                         h=i; k=j; flag=1; break;
    57                     }
    58                 }else if(s[i][j]=='.'){
    59                     if(vis[i]+d[j]==cnt){
    60                         h=i;k=j; flag=1; break;
    61                     }
    62                 }
    63             }
    64             if(flag)  break;
    65         }
    66         if(flag){
    67             cout<<"YES"<<endl;
    68             cout<<h+1<<" "<<k+1<<endl;
    69         }else{
    70             cout<<"NO"<<endl;
    71         }
    72     }
    73     return 0;
    74 }
    View Code

     C题:

    题意:0代表休息,1代表学习,2代表运动,3既可以代表学习又可以代表运动,相邻两天之间做的活不能一样,问最少休息几天

    分析:赛场上没有做出来的dp,写错一个地方。dp[i][j]代表前i天,当第i天为j时的最多活动天数,当第i天为0时,必须休息,所以dp[i][0]就为前i-1天的最大值,当第i天为1或者3时,我们考虑若是工作的话,那必须从距离他最近的一个2或者0再+1,同理i为2的话也是距离他最近的一个1或者0再加1,最后减去最大工作天数即可。非常非常好的一个题目,值得回味

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #include <vector>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <bitset>
    10 #include <cmath>
    11 #include <queue>
    12 #include <stack>
    13 using namespace std;
    14 const int maxn=110;
    15 int dp[maxn][5];
    16 int a[maxn];
    17 int n;
    18 int main()
    19 {
    20     while(cin>>n)
    21     {
    22         for(int i=1;i<=n;i++)
    23             cin>>a[i];
    24         memset(dp,0,sizeof(dp));
    25         int mx=0;
    26         for(int i=1;i<=n;i++){
    27             dp[i][0]=max(dp[i-1][0],max(dp[i-1][1],max(dp[i-1][2],dp[i-1][3])));
    28             if(a[i]==1||a[i]==3)
    29                 dp[i][1]=max(dp[i-1][0],dp[i-1][2])+1;
    30             if(a[i]==2||a[i]==3)
    31                 dp[i][2]=max(dp[i-1][0],dp[i-1][1])+1;
    32             int cnt=max(dp[i][0],max(dp[i][1],dp[i][2]));
    33             mx=max(mx,cnt);
    34         }
    35         cout<<n-mx<<endl;
    36     }
    37     return 0;
    38 }
    View Code

     D题:

    题意:给出每个结点父结点的编号,求最小修改多少个数可以使其成为一课完整的树

    分析:非常好的一个题目,我们来考虑何时是一棵树。当有环时必然不能构成一棵树,当有孤点时必然不能构成一棵树。那我们要做的就是破环,这个地方就用到了并查集,对于有环存在的两个结点,他们通过并查集查询出来的根结点必定相同,但此时有一个结点还未并入集合,因此只可能是存在环,这一点很重要,基于此,我们对每个环进行破环,孤点也可以看做一个自环。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #include <vector>
     6 #include <algorithm>
     7 #include <set>
     8 #include <map>
     9 #include <bitset>
    10 #include <cmath>
    11 #include <queue>
    12 #include <stack>
    13 using namespace std;
    14 const int maxn=200020;
    15 int par[maxn],rankl[maxn],a[maxn];
    16 void init(int n)
    17 {
    18     for(int i=0;i<=n;i++){
    19         par[i]=i;
    20         rankl[i]=0;
    21     }
    22 }
    23 int findl(int x)
    24 {
    25     if(x==par[x])
    26         return x;
    27     else
    28         return par[x]=findl(par[x]);
    29 }
    30 void unite(int x,int y)
    31 {
    32     x=findl(x);
    33     y=findl(y);
    34     if(x==y)  return;
    35     if(rankl[x]<rankl[y])
    36     {
    37         par[x]=y;
    38     }else{
    39         par[y]=x;
    40         if(rankl[x]==rankl[y])  rankl[x]++;
    41     }
    42 }
    43 bool same(int x,int y)
    44 {
    45     return findl(x)==findl(y);
    46 }
    47 int n;
    48 int main()
    49 {
    50     while(cin>>n)
    51     {
    52         int root=-1;
    53         int cnt=0;
    54         init(n);
    55         for(int i=1;i<=n;i++)
    56         {
    57             scanf("%d",&a[i]);
    58             if(i==a[i])   root=i;
    59         }
    60         for(int i=1;i<=n;i++)
    61         {
    62             int fx=findl(i);
    63             int fy=findl(a[i]);
    64             if(fx==fy&&i!=root)
    65             {
    66                 if(root==-1)
    67                     root=i;
    68                 a[i]=root;
    69                 cnt++;
    70             }
    71             unite(fx,fy);
    72         }
    73         printf("%d
    ",cnt);
    74         for(int i=1;i<n;i++)
    75             printf("%d ",a[i]);
    76         printf("%d
    ",a[n]);
    77     }
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    单例对象
    G1回收算法
    Java锁
    VUE开发
    Java线程池
    Java线程状态
    什么是进程,什么是线程
    maven 常用命令
    linux启动脚本,暂停脚本
    delphi---控件使用
  • 原文地址:https://www.cnblogs.com/wolf940509/p/5690562.html
Copyright © 2011-2022 走看看