• Codeforces 486(#277 Div 2) 解题报告


    A:比较简单 判断奇偶  一个公式即可

     1 // File Name: a.cpp
     2 // Author: darkdream
     3 // Created Time: 2014年11月11日 星期二 22时43分28秒
     4 
     5 #include<vector>
     6 #include<list>
     7 #include<map>
     8 #include<set>
     9 #include<deque>
    10 #include<stack>
    11 #include<bitset>
    12 #include<algorithm>
    13 #include<functional>
    14 #include<numeric>
    15 #include<utility>
    16 #include<sstream>
    17 #include<iostream>
    18 #include<iomanip>
    19 #include<cstdio>
    20 #include<cmath>
    21 #include<cstdlib>
    22 #include<cstring>
    23 #include<ctime>
    24 #define LL long long
    25 
    26 using namespace std;
    27 
    28 int main(){
    29    LL n ;
    30    scanf("%lld",&n);
    31    if(n % 2 == 0 )
    32        printf("%d
    ",n/2);
    33    else printf("%d
    ",n/2 -n);
    34 return 0;
    35 }
    View Code

    B:默认 A 所有为 1 先把M[i][j] = 0 的i 行 j列 覆盖成 0  然后再要得到的A 矩阵运算 看能否得出 M

     1 // File Name: b.cpp
     2 // Author: darkdream
     3 // Created Time: 2014年11月11日 星期二 23时03分52秒
     4 
     5 #include<vector>
     6 #include<list>
     7 #include<map>
     8 #include<set>
     9 #include<deque>
    10 #include<stack>
    11 #include<bitset>
    12 #include<algorithm>
    13 #include<functional>
    14 #include<numeric>
    15 #include<utility>
    16 #include<sstream>
    17 #include<iostream>
    18 #include<iomanip>
    19 #include<cstdio>
    20 #include<cmath>
    21 #include<cstdlib>
    22 #include<cstring>
    23 #include<ctime>
    24 #define LL long long
    25 
    26 using namespace std;
    27 int M[200][200];
    28 int A[200][200];
    29 int n , m ;
    30 int dfsr(int k )
    31 {
    32   for(int i = 1;i <= n;i ++)
    33       if(M[i][k] == 0 )
    34           return 0 ;
    35   return 1;
    36 }
    37 int dfsc(int k )
    38 {
    39   //printf("%d
    ",k);
    40   for(int i = 1;i <= m;i ++)
    41   {
    42 //      printf("***%d %d
    ",k,i);
    43       if(M[k][i] == 0 )
    44           return 0 ;
    45   }
    46   return 1;
    47 }
    48 int main(){
    49    scanf("%d %d",&n,&m);
    50    for(int i = 1;i <= n;i ++)
    51        for(int j = 1;j <= m;j ++)
    52        {
    53           scanf("%d",&M[i][j]);
    54           A[i][j] = 1; 
    55        }
    56    for(int i = 1;i <= n;i ++)
    57     for(int j = 1;j <= m;j ++)
    58     {
    59       if(M[i][j] == 0)
    60       {
    61         //printf("***
    ");
    62         for(int s = 1;s <= m ;s ++)
    63         {
    64             A[i][s] = 0 ; 
    65         }
    66         for(int s = 1;s <= n ;s ++)
    67         {
    68             A[s][j] = 0 ; 
    69         }    
    70       }
    71     }
    72    for(int i = 1;i <= n;i ++)
    73    {
    74        for(int j = 1;j <= m;j ++)
    75        {
    76            int tmp = 0 ; 
    77            for(int s = 1 ; s <= m ;s ++ )
    78                tmp |= A[i][s];
    79            for(int s = 1 ; s <= n ;s ++ )
    80                tmp |= A[s][j];
    81            if(tmp != M[i][j])
    82            {
    83               puts("NO");
    84               return 0 ; 
    85            }
    86        }
    87    }
    88    printf("YES
    ");
    89    for(int i = 1;i <= n;i ++)
    90    {
    91       for(int j = 1;j <= m ;j ++)
    92             printf("%d ",A[i][j]);
    93       printf("
    ");
    94    }
    95 return 0;
    96 }
    View Code

    C:这个字符串已知改变的值是已经确定了的。我们只需要看 他怎么样移动才能够覆盖掉半边 要改变的位置,如果他在左边 他只改变左边的是最优的,如果在右边,只

    改变右边的也是最优的,如果穿过中线或者边界一定不是最优的了。

     1 // File Name: c.cpp
     2 // Author: darkdream
     3 // Created Time: 2014年11月11日 星期二 23时28分50秒
     4 
     5 #include<vector>
     6 #include<list>
     7 #include<map>
     8 #include<set>
     9 #include<deque>
    10 #include<stack>
    11 #include<bitset>
    12 #include<algorithm>
    13 #include<functional>
    14 #include<numeric>
    15 #include<utility>
    16 #include<sstream>
    17 #include<iostream>
    18 #include<iomanip>
    19 #include<cstdio>
    20 #include<cmath>
    21 #include<cstdlib>
    22 #include<cstring>
    23 #include<ctime>
    24 #define LL long long
    25 
    26 using namespace std;
    27 char str[100005];
    28 int num[100005];
    29 int vis[100005];
    30 int dp[400005];
    31   int n , p ; 
    32 int solve(int t)
    33 {
    34     if(t <= 0 )
    35     {
    36       return n + t;  
    37     }
    38     if(t > n)
    39         return  t- n ;
    40 }
    41 int main(){
    42   scanf("%d %d",&n,&p);
    43   scanf("%s",&str[1]); 
    44   int sum = 0 ;
    45   int num = 0 ; 
    46   for(int i = 1;i <= n/2;i ++)
    47   {
    48      if(str[i] == str[n-i+1])
    49          continue;
    50      num ++ ; 
    51      int mi = min(str[i],str[n-i+1]) ;
    52      int mx = max(str[i],str[n-i+1]);
    53      sum += min(mx - mi,mi + 26 -mx);
    54      vis[i] = 1; 
    55      vis[n-i+1] = 1; 
    56   }
    57   if(sum == 0 )
    58   {
    59      printf("0
    ");
    60      return 0 ;
    61   }
    62   
    63      int be = 0 ; 
    64      int en = 0 ;
    65      int qd ;
    66      int zd;
    67      if(p > n/2)
    68      {
    69        qd = n/2 +1;
    70        zd = n;
    71      }else {
    72        qd = 1; 
    73        zd = n/2;
    74      }
    75      
    76      for(int i = qd;i <= zd;i ++)
    77      {
    78          if(!be && vis[i] ==1 )
    79              be = i ; 
    80          if(vis[i])
    81             en = i ; 
    82      }
    83      //printf("%d %d
    ",be,en);
    84      if(p >= en)
    85          sum +=  p - be;
    86      else if(p <= be)
    87          sum +=  en - p;
    88      else sum += min(p-be,en-p) + en -be;
    89      printf("%d
    ",sum);
    90 return 0;
    91 }
    View Code

    D:从值最小的点开始每个点都要暴搜整颗树,从某个点开始遍历,这个点要是所有遍历到点的最小值 且遍历到的点要满足 val[x] - val[这个点]  <= d ,子树用树形DP求出,,每搜过一颗树把根标记掉,下次就不能走了。这样就可以得到所有的子树

      1 // File Name: d.cpp
      2 // Author: darkdream
      3 // Created Time: 2014年11月12日 星期三 19时23分45秒
      4 
      5 #include<vector>
      6 #include<list>
      7 #include<map>
      8 #include<set>
      9 #include<deque>
     10 #include<stack>
     11 #include<bitset>
     12 #include<algorithm>
     13 #include<functional>
     14 #include<numeric>
     15 #include<utility>
     16 #include<sstream>
     17 #include<iostream>
     18 #include<iomanip>
     19 #include<cstdio>
     20 #include<cmath>
     21 #include<cstdlib>
     22 #include<cstring>
     23 #include<ctime>
     24 #define LL long long
     25 #define maxn 100005 
     26 using namespace std;
     27 int F1[maxn];
     28 int F2[maxn];
     29 int a[maxn];
     30 int vis[maxn];
     31 vector<int> LIS;
     32 int L;
     33 int find(int x)
     34 {
     35    int l = 0; 
     36    int r = LIS.size() - 1;
     37    int m; 
     38    while(l <= r )
     39    {
     40       m = (l + r) >>  1; 
     41      if(x < LIS[m])
     42      {
     43          l = m  + 1;      
     44      }else r = m - 1;
     45    }
     46    //printf("%d %d %d %d
    ",l,m,a[m],x);
     47    return l; 
     48 }
     49 int main(){
     50      int n; 
     51      scanf("%d",&n);
     52      for(int i = 1;i <= n;i ++)
     53      {
     54         scanf("%d",&a[i]);
     55         int p = upper_bound(LIS.begin(),LIS.end(),a[i]-1) - LIS.begin();
     56         if(p == LIS.size())
     57         {
     58            LIS.push_back(a[i]);
     59         }else{
     60            LIS[p] = a[i];
     61         }
     62         F1[i] = p + 1;  
     63      }
     64      L = LIS.size();
     65      //printf("%d
    ",L);
     66      LIS.clear();
     67      for(int i = n;i >= 1;i --) 
     68      {
     69         int p = find(a[i]);
     70         if(p == LIS.size())
     71             LIS.push_back(a[i]);
     72         else LIS[p] = a[i];
     73         F2[i] = p+1;
     74         //printf("%d %d
    ",i,F2[i]);
     75      }
     76 /*     for(int i = 1;i <= n;i ++)
     77          printf("%d*",F1[i]);
     78      printf("
    ");
     79 */     memset(vis,0,sizeof(vis));
     80      for(int i = 1;i <= n;i ++)
     81      {
     82         // printf("%d ",F2[i]);
     83        if(F1[i] + F2[i] -1== L)
     84            vis[F2[i]] ++ ; 
     85      }
     86      /*for(int i = 1;i <= n;i ++)
     87          printf("%d ",vis[i]);
     88      printf("
    ");*/
     89      //printf("
    ");
     90      for(int i = 1;i <= n;i ++)
     91      {
     92        if(F1[i] + F2[i] -1 < L)
     93           printf("1");
     94        else if(vis[F2[i]] == 1)
     95            printf("3");
     96        else printf("2");
     97      }
     98     
     99 return 0;
    100 }
    View Code

    E:

    题解:

    官方解法2:http://codeforces.com/blog/entry/14678

    YYN解法:http://blog.csdn.net/u013368721/article/details/41030775

    数列a[i]

    F1[i]  表示  以a[i]结尾的最长LIS的长度   顺序遍历二分求得

    F2[i]  表示  以a[i]开头的最长LIS的长度   逆序遍历二分求得

    L是LIS长度,

    然后 YYN 和管方的做法就不用了

    YYN:

     然后分类:

     1)F1[i] + F2[i] - 1 < L 

     2)F1[i] + F2[i] - 1 == L   且 F1[i] 不唯一(这里如何计数唯一和不唯一 需要把所有 F1[i] + F2[i] == L 的统计一遍)

     3)F1[1] + F2[i] - 1 == L 且 F1[i] 唯一

    官方2:

        再设一个数列  F[i] 表示  如果没有 a[i]  LIS 的长度, F[i] = max( 1 <= u <i < v <= n &&a[v] > a[u]   |F1[u]  + F2[v])

       F[i] 需要用到一次线段树 和数组离线来统计 

       然后就是分类  

        1)  F1[i] + F2[i] -1 < L  

        2)    F[i] == L  

        3)    F[i] == L-1

    显然 YYN的做法更巧妙  YM + ORZ

    YYN做法代码:

      1 // File Name: e.cpp
      2 // Author: darkdream
      3 // Created Time: 2014年11月12日 星期三 00时35分31秒
      4 
      5 #include<vector>
      6 #include<list>
      7 #include<map>
      8 #include<set>
      9 #include<deque>
     10 #include<stack>
     11 #include<bitset>
     12 #include<algorithm>
     13 #include<functional>
     14 #include<numeric>
     15 #include<utility>
     16 #include<sstream>
     17 #include<iostream>
     18 #include<iomanip>
     19 #include<cstdio>
     20 #include<cmath>
     21 #include<cstdlib>
     22 #include<cstring>
     23 #include<ctime>
     24 #define LL long long
     25 
     26 using namespace std;
     27 struct node{
     28   int v, p ;
     29   node(int _v ,int _p)
     30   {
     31     v = _v;
     32     p = _p;
     33   }
     34 };
     35 int len = 0 ; 
     36 vector<int>LI;
     37 vector<node> LIS[100005];
     38 int ans[100005];
     39 int np[100005];
     40 int n;
     41 void solve()
     42 {
     43    for(int i = 0;i < len - 1; i ++)
     44    {
     45       int k = LIS[i].size();
     46       if(k == 1)
     47       {
     48          ans[LIS[i][0].p] = 2; 
     49       }
     50    }
     51    int num = LIS[len-1].size();
     52    if(num == 1 )
     53    {
     54          ans[LIS[len-1][0].p] = 2; 
     55    }else{
     56      for(int i = 0 ;i < num;i ++)
     57      {
     58          ans[LIS[i][0].p] = 1; 
     59      }
     60    }
     61    int be = 0;
     62    int en = num -1;
     63    for(int i = len - 2;i >= 1;i --)
     64    {
     65        int num = LIS[i].size(); 
     66        int tbe = -1 ; 
     67        int ten = -1;
     68        int j = 0; 
     69        int s = be; 
     70        {
     71           node tmp = LIS[i][j];
     72           if(tmp.v < LIS[i+1][s].v && tmp.p < LIS[i+1][s].p)
     73           {
     74              if(tbe == -1)
     75              {
     76                 tbe = j ; 
     77              }
     78              ten = j; 
     79           }else if(tmp.v > LIS[i+1][s].v){
     80               
     81           }
     82        }
     83        be = tbe;
     84        en = ten;
     85        if(be == en)
     86        {
     87            ans[LIS[i][be].p] = 2; 
     88        }else
     89          for(int j= be;j <= en;j ++)
     90          {
     91             ans[LIS[i][j].p] = 1; 
     92          }
     93         
     94    }
     95 }
     96 int main(){
     97    int n;
     98    scanf("%d",&n);
     99    len = 0 ; 
    100    for(int i = 1;i <= n;i ++)
    101    {
    102       int t; 
    103       scanf("%d",&t);
    104       int p = upper_bound(LI.begin(),LI.end(),t) - LI.begin();
    105       if(p == LI.size())
    106       {
    107           LI.push_back(t);
    108           len ++;
    109       }
    110       else LI[p] = t;
    111       np[x] = LI[p+1].size() - 1;
    112       LIS[p].push_back(node(t,i));
    113    }
    114    solve();
    115    for(int i =1;i <= n;i ++)
    116        printf("%d",ans[i]+1);
    117 return 0;
    118 }
    View Code
    没有梦想,何谈远方
  • 相关阅读:
    [转]VC++ ^和gcnew
    OPPM 一页纸项目管理 OnePage Project Management
    [转]基础总结篇之五:BroadcastReceiver应用详解 .
    [转]深入浅出Java设计模式之备忘录模式
    [转]面向对象的5条基本设计原则
    [转]UED大全
    [转]VC++动态链接库(DLL)编程深入浅出(zz)
    只有壮年时的不遗余力 才能支撑一生的坎坷与幸福
    [书目20121024]当责 AccountaBility
    node.js入门
  • 原文地址:https://www.cnblogs.com/zyue/p/4093535.html
Copyright © 2020-2023  润新知