zoukankan      html  css  js  c++  java
  • 3.12

    http://codeforces.com/gym/101246

    A题

    B题

    思路:简单模拟,对每一块砖判断它的前后左右是否比它高,如果比他高,它本身为0,否则它是他们的差值和。如果这块砖存在,就加上它的上下两个面。

     1 #include <iostream>
     2 #include<cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include<queue>
     6 #include <map>
     7 using namespace std;
     8 const int maxn=300;
     9 char s[maxn][maxn];
    10 int a[maxn][maxn];
    11 int b[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    12 int main()
    13 {
    14     freopen("input.txt","r",stdin);
    15     freopen("output.txt","w",stdout);
    16     int n,m;
    17     while(~scanf("%d%d",&n,&m))
    18     {
    19         for(int i=0; i<n; i++)
    20             scanf("%s",s[i]);
    21         memset(a,0,sizeof(a));
    22         for(int i=0; i<n; i++)
    23         {
    24             for(int j=0; j<m; j++)
    25                 a[i+1][j+1]=s[i][j]-'0';
    26         }
    27         int ans=0;
    28         for(int i=1; i<=n; i++)
    29             for(int j=1; j<=m; j++)
    30             {
    31                 for(int k=0; k<4; k++)
    32                 {
    33                     int x=i+b[k][0];
    34                     int y=j+b[k][1];
    35                     if(a[x][y]<a[i][j])
    36                         ans+=(a[i][j]-a[x][y]);
    37                 }
    38                 if(a[i][j])
    39                 ans+=2;
    40             }
    41             printf("%d
    ",ans);
    42     }
    43     return 0;
    44 }
    View Code

    C题

    思路:要用bitset去存储它的每一行所对应的列是否有*,然后dp得到最小的ans

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <map>
     7 #include <cmath>
     8 #include <bitset>
     9 #include <bits/stdc++.h>
    10 using namespace std;
    11 const int maxn=25;
    12 bitset <maxn> f[maxn],dp[1<<maxn];
    13 char s[26];
    14 int id[1<<maxn],num[1<<maxn];
    15 int lowbit(int x)
    16 {
    17     return x&-x;
    18 }
    19 int main()
    20 {
    21     freopen("input.txt","r",stdin);
    22     freopen("output.txt","w",stdout);
    23     int n,m;
    24     scanf("%d%d",&n,&m);
    25         for(int i=0;i<n;i++)
    26         {
    27             scanf("%s",s);
    28             for(int j=0;j<m;j++)
    29                 f[i][j]=s[j]=='*';
    30         }
    31         int ans=min(n,m);
    32         for(int i=0;i<maxn;i++)
    33         id[1<<i]=i;
    34         for(int i=1;i<(1<<n);i++)
    35         {
    36             dp[i]=dp[i-lowbit(i)]|f[id[lowbit(i)]];
    37             num[i]=num[i-lowbit(i)]+1;
    38             ans=min(ans,max((int)dp[i].count(),n-num[i]));
    39         }
    40         printf("%d
    ",ans);
    41     return 0;
    42 }
    View Code

    D题

    思路:先由上往下进行存储每个城市被点燃的的最短时间,然后由下往上进行逐步推出从城市1出发是否能够在Vladimir控制时无路可走

     1 #include <iostream>
     2 #include<cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <vector>
     7 using namespace std;
     8 const int maxn=1500;
     9 vector<int> node[maxn];
    10 queue<int> que;
    11 int vis[maxn],pos[maxn],cnt[maxn];
    12 int main()
    13 {
    14     //freopen("input.txt","r",stdin);
    15     //freopen("output.txt","w",stdout);
    16     int n,m,u,v;
    17     while(~scanf("%d%d",&n,&m))
    18     {
    19         for(int i=0;i<m;i++)
    20         {
    21             scanf("%d%d",&u,&v);
    22             node[u].push_back(v);
    23             node[v].push_back(u);
    24         }
    25         memset(vis,0,sizeof(vis));
    26         memset(cnt,0,sizeof(cnt));
    27         memset(pos,0,sizeof(pos));
    28         while(!que.empty()) que.pop();
    29         que.push(1);
    30         vis[1]=1;
    31         int tot=0;
    32         while(!que.empty())
    33         {
    34             int x=que.front();que.pop();
    35             pos[++tot]=x;//从1开始依次经过的节点
    36             for(int i=0;i<(int)node[x].size();i++)
    37             {
    38                 int k=node[x][i];
    39                 if(vis[k]) continue;
    40                 else
    41                 {
    42                     que.push(k);
    43                     vis[k]=vis[x]+1;//城市k于城市x相连且城市x是城市k的上一级
    44                 }
    45             }
    46         }
    47         for(int i=n;i>=2;i--)
    48         {
    49             int k=pos[i];//从节点的最末尾开始依次往上进行搜索
    50             for(int j=0;j<(int)node[k].size();j++)
    51             {
    52                 int x=node[k][j];
    53                 if(vis[k]!=vis[x]+1) continue;
    54                 if(cnt[k]==0) cnt[x]=1;//
    55             }
    56         }
    57         if(cnt[1]==1)
    58             printf("Vladimir
    ");
    59         else
    60             printf("Nikolay
    ");
    61     }
    62     return 0;
    63 }
    View Code

    E题

    思路:使用数组储存当前马车所走的第 i 个弯道,然后遍历所有路口进行下个距离的弯道 i +1进行储存,一直进行到 i +1=m结束

     1 #include <iostream>
     2 #include<cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include<queue>
     6 #include <map>
     7 using namespace std;
     8 const int maxn=400;
     9 int dp[maxn][maxn];
    10 int a[maxn][maxn];
    11 int ans[maxn],p[maxn];
    12 int main()
    13 {
    14     freopen("input.txt","r",stdin);
    15     freopen("output.txt","w",stdout);
    16     int n,m;
    17     while(~scanf("%d",&n))
    18     {
    19         for(int i=1; i<=n; i++)
    20             for(int j=1; j<=n; j++)
    21                 scanf("%d",&a[i][j]);
    22         scanf("%d",&m);
    23         for(int i=1; i<=m; i++)
    24             scanf("%d",&p[i]);
    25         memset(dp,0,sizeof(dp));
    26         dp[0][1]=1;
    27         for(int i=1; i<=m; i++)
    28         {
    29             for(int j=1; j<=n; j++)
    30             {
    31                 if(dp[i-1][j])
    32                 {
    33                     for(int k=1; k<=n; k++)
    34                         if(a[j][k]==p[i])
    35                             dp[i][k]=1;
    36                 }
    37             }
    38         }
    39         int k=0;
    40         for(int i=1; i<=n; i++)
    41             if(dp[m][i])
    42                 ans[k++]=i;
    43         printf("%d
    ",k);
    44         for(int i=0; i<k; i++)
    45             printf("%d%c",ans[i],i==k-1?'
    ':' ');
    46     }
    47     return 0;
    48 }
    View Code

    F题

    思路:题意是电梯当前所在楼层为m,上来n个人依次按下n个不同的楼层,电梯从1~n开始运行,如果在去往a[1]的过程中经过a[k],则在a[k]停了下来。利用从大到小和从小到大两个优先队列,对电梯的行进的途径楼层进行储存,然后放入结果数组,注意标记即可。

     1 #include <iostream>
     2 #include<cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include<queue>
     6 #include <map>
     7 using namespace std;
     8 const int maxn=300;
     9 int a[maxn];
    10 int ans[maxn],flag[maxn];
    11 priority_queue<int,vector<int>,greater<int> >que1;
    12 priority_queue<int>que2;
    13 int main()
    14 {
    15     freopen("input.txt","r",stdin);
    16     freopen("output.txt","w",stdout);
    17     int n,m;
    18     while(~scanf("%d%d",&n,&m))
    19     {
    20         for(int i=0; i<n; i++)
    21         {
    22             scanf("%d",&a[i]);
    23         }
    24         while(!que1.empty())
    25         {
    26             que1.pop();
    27         }
    28         while(!que2.empty())
    29         {
    30             que2.pop();
    31         }
    32         memset(flag,0,sizeof(flag));
    33         int p=0;
    34         for(int i=0; i<n; i++)
    35         {
    36             if(flag[i])
    37                 continue;
    38             if(m>a[i])
    39             {
    40                 for(int j=i; j<n; j++)
    41                     if(a[i]<=a[j]&&a[j]<=m&&!flag[j])
    42                     {
    43                         flag[j]=1;
    44                         que2.push(a[j]);
    45                     }
    46                 while(!que2.empty())
    47                 {
    48                     ans[p++]=que2.top();
    49                     que2.pop();
    50                 }
    51             }
    52             if(m<=a[i])
    53             {
    54                 for(int j=i; j<n; j++)
    55                     if(a[i]>=a[j]&&a[j]>=m&&!flag[j])
    56                     {
    57                         flag[j]=1;
    58                         que1.push(a[j]);
    59                     }
    60                 while(!que1.empty())
    61                 {
    62                     ans[p++]=que1.top();
    63                     que1.pop();
    64                 }
    65             }
    66             m=a[i];
    67         }
    68         for(int i=0; i<n-1; i++)
    69             printf("%d ",ans[i]);
    70         printf("%d
    ",ans[n-1]);
    71     }
    72     return 0;
    73 }
    View Code

    G题

    H题

    I题

    J题

    思路:对每一个点都要对两点之间的距离进行遍历,利用三分找出两个点之间的距离,然后不断缩小范围求出最小的差的绝对值和此时的所在的位置

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <queue>
     6 #include <map>
     7 #include <cmath>
     8 using namespace std;
     9 const int maxn=500;
    10 const double eps=1e-12;
    11 double a[maxn];
    12 int n,id;
    13 double cal(double pre)
    14 {
    15     double len,len1;
    16     len1=400000000;
    17     for(int i=0; i<n; i++)
    18     {
    19         len=0;
    20         for(int j=i+1; j<n; j++)
    21         {
    22             len+=fabs(a[i]+(j-i)*pre-a[j]);
    23         }
    24         for(int j=i-1; j>=0; j--)
    25         {
    26             len+=fabs(a[i]+(j-i)*pre-a[j]);
    27         }
    28         if(len<len1)
    29         {
    30             len1=len;
    31             id=i;
    32         }
    33     }
    34     return len1;
    35 }
    36 int solve()
    37 {
    38     scanf("%d",&n);
    39     for(int i=0; i<n; i++)
    40         scanf("%lf",&a[i]);
    41     double  l=0,r=1000000;
    42     while(r-l>=eps)
    43     {
    44         //printf("%.5lf
    ",cal(l));
    45         double mid=(r+l)/2.0;
    46         double midd=(mid+r)/2.0;
    47         if(cal(mid)>cal(midd)) l=mid;
    48         else r=midd;
    49     }
    50     double pre=cal(l)<cal(r)?l:r;
    51     double len;
    52     len=cal(pre);
    53     printf("%.4lf
    ",len);
    54     for(int i=0; i<n; i++)
    55     {
    56         printf("%.10lf%c",a[id]+(i-id)*pre,i==n-1?'
    ':' ');
    57     }
    58     return 0;
    59 }
    60 int main()
    61 {
    62     freopen("input.txt","r",stdin);
    63     freopen("output.txt","w",stdout);
    64     solve();
    65     return 0;
    66 }
    View Code

    K题

    L题

  • 相关阅读:
    nginx
    同步和异步
    什么是ACID
    关系型数据库特点小结
    js 简单小知识
    join 和 left join 和 right join的区别?
    mysql中having和where区别?
    include和require区别
    什么是脏读,不可重复,幻读?
    Mysql常见面试题
  • 原文地址:https://www.cnblogs.com/wang-ya-wei/p/6556300.html
Copyright © 2011-2022 走看看