zoukankan      html  css  js  c++  java
  • Codeforces Round #420 (Div. 2)

      A题,水题,只要暴力即可,要注意的是题意要理解清楚。

      B题,枚举每一个x作为矩形的右边,那么其中的贡献是可以用等差数列累和公式计算的,最后对所有可能的答案取一个max即可。该题很友好,使用floor没有被卡精度= =。

      C题,由于题目是保证了一定能够使得满足要求,那么如果remove的时候这个栈不是递减的只需要给它排序一下即可。实际上并不需要对其这样模拟(也不可以这样模拟),具体做法见代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int N = 3e5 + 10;
     4 typedef long long ll;
     5 
     6 int n;
     7 char s[100];
     8 vector<int> v;
     9 
    10 int main()
    11 {
    12     cin >> n;
    13     stack<int> S;
    14     int ans = 0;
    15     int now = 0;
    16     for(int i=1;i<=2*n;i++)
    17     {
    18         scanf("%s",s);
    19         if(strcmp(s, "add") == 0)
    20         {
    21             int x;
    22             scanf("%d",&x);
    23             S.push(x);
    24         }
    25         else
    26         {
    27             now++;
    28             if(!S.empty())
    29             {
    30                 if(S.top() != now)
    31                 {
    32                     ans++;
    33                     while(!S.empty()) S.pop();
    34                 }
    35                 else S.pop();
    36             }
    37         }
    38     }
    39     cout << ans << endl;
    40     return 0;
    41 }
    C

      

      D题,最短路问题。采用如下的建边方式:

      但是如果n方建边一定会爆内存,因此不建边,直接for一遍更新dis数组即可。代码如下:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int N = 1e4 + 10;
     4 typedef long long ll;
     5 typedef pair<int,int> pii;
     6 const int inf = 0x3f3f3f3f;
     7 
     8 int n,m,k;
     9 pii p[N];
    10 int d[N], inq[N];
    11 int s, ed;
    12 int spfa()
    13 {
    14     memset(d, inf, sizeof d);
    15     d[s] = 0;
    16     inq[s] = 1;
    17     queue<int> Q;
    18     Q.push(s);
    19     while(!Q.empty())
    20     {
    21         int u = Q.front(); Q.pop();
    22         inq[u] = 0;
    23         for(int i=1;i<=k;i++)
    24         {
    25             if(i != u)
    26             {
    27                 int val = inf;
    28                 int dx = abs(p[u].first - p[i].first);
    29                 int dy = abs(p[u].second - p[i].second);
    30                 if(dx + dy == 1) val = 0;
    31                 else if(dx <= 2 || dy <= 2) val = 1;
    32                 if(d[i] > d[u] + val)
    33                 {
    34                     d[i] = d[u] + val;
    35                     if(inq[i] == 0)
    36                     {
    37                         inq[i] = 1;
    38                         Q.push(i);
    39                     }
    40                 }
    41             }
    42         }
    43     }
    44     return d[ed] == inf ? -1 : d[k];
    45 }
    46 
    47 int main()
    48 {
    49     cin >> n >> m >> k;
    50     bool ok = 0;
    51     for(int i=1;i<=k;i++)
    52     {
    53         int x, y;
    54         scanf("%d%d",&x,&y);
    55         p[i] = pii(x, y);
    56         if(x == n && y == m) ok = true, ed = i;
    57         if(x == 1 && y == 1) s = i;
    58     }
    59     if(!ok)
    60     {
    61         k++;
    62         p[k] = pii(n + 1, m + 1);
    63         ed = k;
    64     }
    65     cout << spfa() << endl;
    66     return 0;
    67 }
    D

      E题,dp转移方程很容易想到,同时由于ci很小,k很大,考虑使用矩阵快速幂处理递推。代码如下:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 typedef pair<int,int> pii;
      5 const int mod = 1e9 + 7;
      6 
      7 void add(int &a,int b)
      8 {
      9     a += b;
     10     if(a < 0) a += mod;
     11     a %= mod;
     12 }
     13 
     14 struct matrix
     15 {
     16     int e[16+5][16+5],n,m;
     17     matrix() {}
     18     matrix(int _n,int _m): n(_n),m(_m) {memset(e,0,sizeof(e));}
     19     matrix operator * (const matrix &temp)const
     20     {
     21         matrix ret = matrix(n,temp.m);
     22         for(int i=1;i<=ret.n;i++)
     23         {
     24             for(int j=1;j<=ret.m;j++)
     25             {
     26                 for(int k=1;k<=m;k++)
     27                 {
     28                     add(ret.e[i][j],1LL*e[i][k]*temp.e[k][j]%mod);
     29                 }
     30             }
     31         }
     32         return ret;
     33     }
     34     matrix operator + (const matrix &temp)const
     35     {
     36         matrix ret = matrix(n,m);
     37         for(int i=1;i<=n;i++)
     38         {
     39             for(int j=1;j<=m;j++)
     40             {
     41                 add(ret.e[i][j],(e[i][j]+temp.e[i][j])%mod);
     42             }
     43         }
     44         return ret;
     45     }
     46     void getE()
     47     {
     48         for(int i=1;i<=n;i++)
     49         {
     50             for(int j=1;j<=m;j++)
     51             {
     52                 e[i][j] = i==j?1:0;
     53             }
     54         }
     55     }
     56 };
     57 
     58 matrix qpow(matrix temp,ll x)
     59 {
     60     int sz = temp.n;
     61     matrix base = matrix(sz,sz);
     62     base.getE();
     63     while(x)
     64     {
     65         if(x & 1) base = base * temp;
     66         x >>= 1;
     67         temp = temp * temp;
     68     }
     69     return base;
     70 }
     71 
     72 void print(matrix p)
     73 {
     74     int n = p.n;
     75     int m = p.m;
     76     for(int i=1;i<=n;i++)
     77     {
     78         for(int j=1;j<=m;j++)
     79         {
     80             printf("%d ",p.e[i][j]);
     81         }
     82         cout << endl;
     83     }
     84 }
     85 
     86 int main()
     87 {
     88     int n;
     89     ll k;
     90     cin >> n >> k;
     91     matrix ans = matrix(16, 16);
     92     ans.e[1][1] = 1;
     93     for(int i=1;i<=n;i++)
     94     {
     95         ll x, y;
     96         int h;
     97         scanf("%I64d%I64d%d",&x,&y,&h);
     98         if(x >= k) continue;
     99         h++;
    100         matrix temp = matrix(h, h);
    101         for(int i=1;i<=h;i++)
    102         {
    103             temp.e[i][i] = 1;
    104             for(int j=-1;j<=1;j++)
    105             {
    106                 if(i+j>=1) temp.e[i+j][i] = 1;
    107                 if(i+j<=h) temp.e[i+j][i] = 1;
    108             }
    109         }
    110         ans = ans * qpow(temp, min(y, k) - x);
    111     }
    112     cout << ans.e[1][1] << endl;
    113     return 0;
    114 }
    E

     

  • 相关阅读:
    OC3(字符串,值类)
    OC2(初始化方法)
    OC1(类和对象)
    postgresql 时间戳格式为5分钟、15分钟
    centos添加ftp用户并禁止外切目录
    postgresql 判断日期是否合法
    tigerVNC的简单使用教程(CentOS的远程桌面连接)
    linux awk解析csv文件
    由windows向linux上传下载文件方法
    codeblocks linux编译告警乱码解决办法
  • 原文地址:https://www.cnblogs.com/zzyDS/p/7106418.html
Copyright © 2011-2022 走看看