zoukankan      html  css  js  c++  java
  • 20171226小测

    于是今天上午有了一场愉悦的考试。
    这里只是来写总结和题解的。

    T1(中位数之塔):
    链接:EZOJ_Alpha:P1018
    一道找规律题,先二分答案然后在找规律线性时间验证。
    显然先通过大小比较把输入转成0、1序列。
    规律是什么呢?如果有两个连续的0或者1,则他们会每次向中间错一格,最后谁先到中间那么答案就是谁。
    其实就是去比较距离。
    如果两者均不存在,则最下面一行一定是01间隔的,手玩一下可发现规律。
    然后我是怎么挂的呢?看出两个0上面全都是0,两个1上面全都是1,然后不会做,弃坑了。
    交了30分暴力,然后数组开小,爆零啦QAQ。

    然后上代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define debug cout
     6 using namespace std;
     7 const int maxn=1e5+1e2;
     8 
     9 int in[maxn<<1],nums[maxn<<1];
    10 int n,dep;
    11 
    12 inline int findcon(int pos,int tar) {
    13     int l = pos , r = pos;
    14     while( l > 1 && ( nums[l]!=tar || nums[l-1]!=tar) )
    15         --l;
    16     while( r < ( n * 2 - 1 ) && ( nums[r]!=tar || nums[r+1]!=tar ) )
    17         ++r;
    18     return min( pos - l , r - pos );
    19 }
    20 inline void cov(int x) {
    21     for(int i=1;i<n<<1;i++)
    22         nums[i] = ( in[i] >= x );
    23 }
    24 inline bool judge(int x) {
    25     cov(x);
    26     int dze = findcon(n,0) , don = findcon(n,1);
    27     if( dze != don )
    28         return dze > don;
    29     return ! ( (dep + nums[n] ) & 1 );
    30 }
    31 inline int getans() {
    32     int ll = 1 , rr = ( n << 1 ) - 1 , mid;
    33     while( rr != ll + 1 ) {
    34         mid = ( ll + rr ) >> 1;
    35         if( !judge(mid) )
    36             rr = mid;
    37         else ll = mid;
    38     }
    39     return ll;
    40 }
    41 
    42 int main() {
    43     scanf("%d",&n);
    44     dep = ( n + 1 ) >> 1;
    45     for(int i=1;i<n<<1;i++)
    46         scanf("%d",in+i);
    47     
    48     printf("%d
    ",getans());
    49     
    50     return 0;
    51 }
    View Code

    T2(宝石迷阵):
    链接:EZOJ_Alpha:P1017
    让符合某种条件的东西最多,显然拆点网络流。然而如何保证90度转角?
    考虑转了90度的两个点一定不在同一行,按行染色即可。
    考场AC。

    上代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<queue>
      6 #define debug cout
      7 using namespace std;
      8 const int maxn=5e+3+1e2,maxm=maxn*50;
      9 const int inf=0x3f3f3f3f;
     10 
     11 int s[maxn],t[maxm],nxt[maxm],f[maxm];
     12 int dep[maxn];
     13 char in[55][55];
     14 int n,m,st,ed;
     15 
     16 inline void coredge(int from,int to,int flow) {
     17     static int cnt = 1;
     18     t[++cnt] = to,
     19     f[cnt] = flow,
     20     nxt[cnt] = s[from],
     21     s[from] = cnt;
     22 }
     23 inline void addedge(int from,int to,int flow) {
     24     coredge(from,to,flow);
     25     coredge(to,from,0);
     26 }
     27 
     28 inline bool bfs() {
     29     memset(dep,-1,sizeof(dep));
     30     dep[st] = 0;
     31     queue<int> q;
     32     q.push(st);
     33     while( q.size() ) {
     34         const int pos = q.front(); q.pop();
     35         for(int at=s[pos];at;at=nxt[at])
     36             if( f[at] && !~dep[t[at]] ) {
     37                 dep[t[at]] = dep[pos] + 1;
     38                 q.push(t[at]);
     39             }
     40     }
     41     return ~dep[ed];
     42 }
     43 inline int dfs(int pos,int flow) {
     44     if( pos == ed )
     45         return flow;
     46     int ret = 0 , now = 0;
     47     for(int at=s[pos];at;at=nxt[at])
     48         if( f[at] && dep[t[at]] > dep[pos] ) {
     49             now = dfs(t[at],min(flow,f[at]));
     50             ret += now , flow -= now,
     51             f[at] -= now , f[at^1] += now;
     52             if( !flow )
     53                 return ret;
     54         }
     55     if( !ret )
     56         dep[pos] = -1;
     57     return ret;
     58 }
     59 inline int dinic() {
     60     int ret = 0 , now = 0;
     61     while( bfs() ) {
     62         while( now = dfs(st,inf) )
     63             ret += now;
     64     }
     65     return ret;
     66 }
     67 
     68 inline int cov(int xx,int yy,int sta=0) { // 0 means full point or in point , 1 means out point.
     69     return ( ( xx - 1 ) * m + yy ) * 2 - 1 + sta;
     70 }
     71 inline bool judge(int xx,int yy) {
     72     return xx > 0 && xx <= n && yy > 0 && yy <= m && in[xx][yy]=='.';
     73 }
     74 inline void explain() {
     75     st = cov(n,m,1) + 1 , ed = cov(n,m,1) + 2;
     76     for(int i=1;i<=n;i++)
     77         for(int j=1;j<=m;j++)
     78             if( in[i][j] == '.' && ( ( i + j ) & 1 ) ) {
     79                 if( i & 1 )
     80                     addedge(st,cov(i,j),1);
     81                 else
     82                     addedge(cov(i,j),ed,1);
     83             }
     84     for(int i=1;i<=n;i++)
     85         for(int j=1;j<=m;j++)
     86             if( in[i][j] == '.' && ! ( ( i + j ) & 1 ) ) {
     87                 addedge(cov(i,j,0),cov(i,j,1),1);
     88                 if( i & 1 ) {
     89                     if( judge(i-1,j) )
     90                         addedge(cov(i,j,1),cov(i-1,j),1);
     91                     if( judge(i+1,j) )
     92                         addedge(cov(i,j,1),cov(i+1,j),1);
     93                     if( judge(i,j+1) )
     94                         addedge(cov(i,j+1),cov(i,j,0),1);
     95                     if( judge(i,j-1) )
     96                         addedge(cov(i,j-1),cov(i,j,0),1);
     97                 }
     98                 else {
     99                     if( judge(i-1,j) )
    100                         addedge(cov(i-1,j),cov(i,j,0),1);
    101                     if( judge(i+1,j) )
    102                         addedge(cov(i+1,j),cov(i,j,0),1);
    103                     if( judge(i,j+1) )
    104                         addedge(cov(i,j,1),cov(i,j+1),1);
    105                     if( judge(i,j-1) )
    106                         addedge(cov(i,j,1),cov(i,j-1),1);
    107                 }
    108             }
    109 }
    110 
    111 int main() {
    112     scanf("%d%d",&n,&m);
    113     for(int i=1;i<=n;i++)
    114         scanf("%s",in[i]+1);
    115     
    116     explain();
    117     
    118     printf("%d
    ",dinic());
    119     
    120     return 0;
    121 }
    View Code

    T3(SiriusRen的卡牌):
    链接:EZOJ_Alpha:P1016
    首先先Orz一发SiriusRen,线段树巨佬(狂魔?)。
    既然这样那么这道题就一定也是线段树了,考虑把一个属性a排序后枚举,那么对于ai小于now的i,我们需要在另外两个属性中选择一个更大;而ai大于now的i,我们需要两个属性均比他大。
    用线段树维护另外两个属性(x,y)的关系,对于属性a比now小的i,(x,y)形成一个递降的阶梯。对于属性a比now大的i,对
    他们的(x,y)连续取平均值形成两条线。我们对于now这个值的答案就是这些东西和(maxx,maxy)围成的面积。
    线段树维护区间赋值即可。然而需要orz一发SiriusRen的写法:通过维护区间min和max简单地实现区间赋值。
    我考场上怎么死的?推出来东西了,不会维护,最后28分暴力滚粗。

    最后上代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define lli long long int
      6 #define debug cout
      7 using namespace std;
      8 const int maxn=5e5+1e2;
      9 //New operation learnt from RYC.
     10 
     11 struct SegmentTree {
     12     int l[maxn<<3],r[maxn<<3],lson[maxn<<3],rson[maxn<<3];
     13     lli mxv[maxn<<3],miv[maxn<<3],sum[maxn<<3],lazy[maxn<<3];
     14     int cnt;
     15     
     16     inline void build(int pos,int ll,int rr) {
     17         l[pos] = ll , r[pos] = rr;
     18         if( ll == rr )
     19             return;
     20         const int mid = ( ll + rr ) >> 1;
     21         build(lson[pos]=++cnt,ll,mid);
     22         build(rson[pos]=++cnt,mid+1,rr);
     23     }
     24     inline void set(int pos,lli x) {
     25         mxv[pos] = miv[pos] = lazy[pos] = x;
     26         sum[pos] = x * ( r[pos] - l[pos] + 1 );
     27     }
     28     inline void push(int pos) {
     29         if( lazy[pos] ) {
     30             if( lson[pos] )
     31                 set(lson[pos],lazy[pos]);
     32             if( rson[pos] )
     33                 set(rson[pos],lazy[pos]);
     34             lazy[pos] = 0;
     35         }
     36     }
     37     inline void up(int pos) {
     38         sum[pos] = sum[lson[pos]] + sum[rson[pos]];
     39         mxv[pos] = max( mxv[lson[pos]] , mxv[rson[pos]] );
     40         miv[pos] = min( miv[lson[pos]] , miv[rson[pos]] );
     41     }
     42     inline void update(int pos,int ll,int rr,lli x) {
     43         if( rr < l[pos] || r[pos] < ll || x <= miv[pos] )
     44             return;
     45         if( ll <= l[pos] && r[pos] <= rr && x >= mxv[pos] ) {
     46             set(pos,x);
     47             return;
     48         }
     49         push(pos);
     50         update(lson[pos],ll,rr,x);
     51         update(rson[pos],ll,rr,x);
     52         up(pos);
     53     }
     54     inline lli full() {
     55         return sum[1];
     56     }
     57     inline lli query(int pos,int ll,int rr) {
     58         if( rr < l[pos] || r[pos] < ll )
     59             return 0;
     60         if( ll <= l[pos] && r[pos] <= rr )
     61             return sum[pos];
     62         push(pos);
     63         return query(lson[pos],ll,rr) + query(rson[pos],ll,rr);
     64     }
     65 }st;
     66 
     67 struct Node {
     68     int zz,xx,yy;
     69     friend bool operator < (const Node &a,const Node &b) {
     70         return a.zz < b.zz;
     71     }
     72 }ns[maxn];
     73 
     74 lli zz,xx,yy,ans;
     75 int n;
     76 
     77 inline void init() {
     78     sort(ns+1,ns+1+n);
     79     st.build(st.cnt=1,1,xx);
     80 }
     81 
     82 inline void getans() {
     83     for(int i=1;i<=n;i++)
     84         st.update(1,1,ns[i].xx,ns[i].yy);
     85     for(int i=zz,j=n;i;i--) {
     86         while( ns[j].zz == i ) {
     87             st.update(1,1,xx,ns[j].yy);
     88             st.update(1,1,ns[j].xx,yy);
     89             j--;
     90         }
     91         ans += xx * yy - st.query(1,1,xx);
     92     }
     93 }
     94 
     95 int main() {
     96     scanf("%d%lld%lld%lld",&n,&zz,&xx,&yy);
     97     for(int i=1;i<=n;i++)
     98         scanf("%d%d%d",&ns[i].zz,&ns[i].xx,&ns[i].yy);
     99     
    100     init();
    101     getans();
    102     
    103     printf("%lld
    ",ans);
    104     
    105     return 0;
    106 }
    View Code

    最后关于为什么我管这个OJ叫EZOJ_Alpha?
    因为我曾经建立过一个局域网专用的基于HUSTOJ的EZOJ,上面有200+题,1k+评测记录,然后被我不小心rm -rf /*了......

  • 相关阅读:
    java去除字符串中的空格、回车、换行符、制表符
    Tomcat 7 'javax.el.ELException' 的解决方式(failed to parse the expression [${xxx}])
    quartz CronExpression表达式
    iconMoon:字体图标(iconfont)解决方案及使用教程
    小程序:前端防止用户重复提交&即时消息(IM)重复发送问题解决
    小程序:位置信息(Location)及微信小程序LBS解决方案实践
    小程序:web-view采坑指南
    小程序:如何让scroll-view包含内容完整滚动
    小程序:如何在wxml页面中调用JavaScript函数
    小程序:怎么在两层列表循环(wx:for)的时候判断是否为最后一个元素
  • 原文地址:https://www.cnblogs.com/Cmd2001/p/8119915.html
Copyright © 2011-2022 走看看