$ NOIp $ popular recording group to do title

\ ([NOIp2014] \) spiral matrix

\(Sol\)

Direct simulation, once an entire row or take an entire column. Complexity \ (O (n-) \) .

\(Code\)

#include<bits/stdc++.h>
#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
#define yes(i,a,b) for(Ri i=a;i>=b;--i)
#define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define db double
#define inf 2147483647
using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
int n,s,x,z,y,nx,ny,tx,ty,nd,ex,ey,nw;
il bool ck()
{
    Ri x1=nx,x2=tx,y1=ny,y2=ty;
    if(x1>x2)swap(x1,x2);if(y1>y2)swap(y1,y2);
    return (ex>=x1 && ex<=x2 && ey>=y1 && ey<=y2);
}
il int calc(){return abs(nx-ex)+abs(ny-ey);}
int main()
{
    n=read(),ex=read(),ey=read();
    if(ex==1 && ey==1){printf("1\n");return 0;}
    nx=ny=nd=1;nw=1;
    while(nd<=n*n)
    {
        if(nw==1){tx=nx,ty=n-y;++s;}
        if(nw==2){tx=n-x,ty=ny;++y;}
        if(nw==3){tx=nx,ty=z+1;++x;}
        if(nw==4){tx=s+1,ty=ny;++z;}
        if(ck()){printf("%d\n",nd+calc());break;}
        nd+=abs(nx-tx)+abs(ny-ty);nx=tx,ny=ty;++nw;if(nw>4)nw=1;
    }
    return 0;
}
    

\ ([NOIp2014] \) sub-matrix

\(Sol\)

Simple search can obtain \ (80pts \) . Think of search optimization is not much (in fact, I will rarely), so this problem can be directly memory search. Specifically, first row to be selected search out, and then search to choose a column when the memory of the line.

\ (UPD: \) . When the search line also seems to be the memory of the memory of the column but found enough by this problem.

\(Code\)

#include<bits/stdc++.h>
#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
#define yes(i,a,b) for(Ri i=a;i>=b;--i)
#define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define db double
#define inf 2100000000
using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
const int N=20;
int n,m,r,c,a[N][N],b[N],d[N],as=inf,ct,f[20][20];
il void init(){mem(f,-1);}
il int dfs2(Ri nw,Ri lst,Ri sum)
{
    if(nw>r)return 0;
    Ri ret=inf;
    if(f[nw][lst]!=-1)return f[nw][lst];
    go(i,lst+1,n-r+nw)
    {
        d[nw]=i;Ri tmp=0;bool fl=1;
        go(j,2,c){tmp+=abs(a[i][b[j]]-a[i][b[j-1]]);if(tmp>=as){fl=0;break;}}
        if(!fl)continue;
        if(nw!=1)go(j,1,c){tmp+=abs(a[i][b[j]]-a[d[nw-1]][b[j]]);if(tmp>=as){fl=0;break;}}
        if(!fl)continue;
        ret=min(ret,dfs2(nw+1,i,tmp)+tmp);
    }
    return f[nw][lst]=ret;
}
il void dfs1(Ri nw,Ri lst)
{
    if(nw>c){init();as=min(dfs2(1,0,0),as);return;}
    go(i,lst+1,m-c+nw)
        b[nw]=i;dfs1(nw+1,i);
}
int main()
{
    n=read(),m=read(),r=read(),c=read();
    go(i,1,n)go(j,1,m)a[i][j]=read();
    dfs1(1,0);
    printf("%d\n",as);
    return 0;   
}

\ ([NOIp2015] \) salesman

\(Sol\)

A more direct idea is for each inquiry, enumerate gone furthest position, and other direct election (where you can maintain the tree line with what) do so .... complexity is about \ (O (n 2logn ^) \) , to obtain \ (60pts \) is not a problem.

Consider this: first direct selection \ (A_i \) before \ (X \) large rounding first and then try. \ (X \) large \ (A_i \) to select a further option set. \ (A_i \ ) before \ (X \) large contribution is \ (\ SUM a + D * 2 \) , and now you want to discard \ (x \) in exchange for \ (the y-\) , then do so may make contributions to increase \ ((D_y -D) * 2-A_x + a_y \) . select one of the biggest contributions can in fact simply select \ (D_y * 2 + a_y \ ) maximum can be, so you can maintain the direct use of an array.

\(Code\)

#include<bits/stdc++.h>
#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
#define yes(i,a,b) for(Ri i=a;i>=b;--i)
#define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define db double
#define inf 2147483647
using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
const int N=100010;
int n,ct,sa[N],maxd[N],maxf[N];
struct nd{int a,d;}t[N];
il bool cmp1(nd x,nd y){return x.d<y.d;}
il bool cmp(nd x,nd y){return x.a>y.a;}
int main()
{
    n=read();
    go(i,1,n)t[i].d=read();
    go(i,1,n)t[i].a=read();
    sort(t+1,t+n+1,cmp);
    go(i,1,n)if(t[i].a==0){n=i-1;break;}
    go(i,1,n)sa[i]=sa[i-1]+t[i].a,maxd[i]=max(maxd[i-1],t[i].d);
    yes(i,n,1)maxf[i]=max(maxf[i+1],t[i].d*2+t[i].a);
    go(i,1,n)printf("%lld\n",max(sa[i]+maxd[i]*2,sa[i-1]+maxf[i+1]));
    return 0;
}

\ ([NOIp2015] \) summing

\(Sol\)

Is intended to simplify the problem, the tape is score: \ (\ sum_ {I <J, (JI) \ &}. 1 = 0 (I + J) (num_i num_j +) \) .

Direct enumeration of the same color \ (i, J \) , \ (the Check \ (JI) \) whether the accumulation is even answer, you can get \ (80pts \) . If you omit \ (check () \) This step just fine. In fact, according to the parity can be grouped in the same group, the same color as long as it can generate contributions to the answers.

Suppose \ ([l, r] \ ) interval is a color, the cumulative answer:

\(\sum_{i=l}^{r}\sum _{j=i+1}^r(i+j)(num_i+num_j)\)

\(=\sum_{i=l}^r i*num_i*(r-l-1)+\sum_{i=l}^{r}\sum _{j=i}^r i*num_j\)

\(=\sum_{i=l}^r i*num_i*(r-l-1)+\sum_{i=l}^{r}i *\sum_{i=l}^r num_i\)

Note that Japanese sentence \ (l = r \) conditions.

\(Code\)

#include<bits/stdc++.h>
#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
#define ll long long    if(ct>1)as+=1LL*s3*(ct-2)%mod+1LL*s1*s2%mod;as%=mod;s1=s2=s3=ct=0;

using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
const int N=100010,mod=10007;
int n,m,as,n1,n2;
struct nd{int num,col,pos;}a[N],b[N];
il bool cmp(nd x,nd y){return x.col<y.col;}
int main()
{
    freopen("1.in","r",stdin);
    n=read(),m=read();
    go(i,1,n)if(i&1)a[++n1].num=read(),a[n1].pos=i;else b[++n2].num=read(),b[n2].pos=i;
    n1=n2=0;
    go(i,1,n)if(i&1)a[++n1].col=read();else b[++n2].col=read();
    sort(a+1,a+n1+1,cmp);sort(b+1,b+n2+1,cmp);
    Ri s1=0,s2=0,s3=0,ct=0;
    go(i,1,n1)
    {
    s1+=a[i].num,s2+=a[i].pos,s3+=1LL*a[i].num*a[i].pos%mod,++ct;
    s1%=mod,s2%=mod,s3%=mod;
    if(a[i].col==a[i+1].col)continue;
    if(ct>1)as+=1LL*s3*(ct-2)%mod+1LL*s1*s2%mod;as%=mod;s1=s2=s3=ct=0;
    }
    s1=s2=s3=ct=0;
    go(i,1,n2)
    {
    s1+=b[i].num,s2+=b[i].pos,s3+=1LL*b[i].num*b[i].pos%mod,++ct;
    s1%=mod,s2%=mod,s3%=mod;
    if(b[i].col==b[i+1].col)continue;
    if(ct>1)as+=1LL*s3*(ct-2)%mod+1LL*s1*s2%mod;as%=mod;s1=s2=s3=ct=0;
    }
    printf("%d\n",as);
    return 0;
}

\ ([NOIp2016] \) harbor

\(Sol\)

Open a queue save the current time as the end of \ (24 \) arriving within hours of tourists (including time and international). An array \ (s [i] \) indicates that the current queue of Chinese nationality as \ (i \) visitors how many a variable \ (nw \) record number of tourists of different nationalities have currently in the queue, because time is increasing ensure that the input can be done online, no need to do off-line. every time a new boat, put the team first time visitors to remove illegal, by the way maintenance under \ (s [i] \) , if there \ (s [i] \) thus becomes \ (0 \) , and then \ (- nw \) . then Join in the tail boat tourists, maintenance of S $ [i] \ (, if \) S [i] $ therefore becomes \ (1 \) , so \ (++ nw \) . the last direct output \ (nw \) , enter the next cycle to the next.

\(Code\)

#include<bits/stdc++.h>
#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
const int N=100010;
int n,ct,q[N*3],l=1,r,s[N*3],nw;
struct nd{int t,k;}a[N*3];
int main()
{
    n=read();
    go(i,1,n)
    {
    Ri t=read(),k=read();
    go(i,1,k)
    {
        Ri kk=read();
        a[++ct]=(nd){t,kk};q[++r]=ct;
        ++s[kk];if(s[kk]==1)++nw;
    }
    while(a[q[l]].t<=t-86400){if(!(--s[a[q[l]].k]))--nw;++l;}
    printf("%d\n",nw);
    }
    return 0;
}

\ ([NOIp2017] \) board

$Sol $

Looks like a very searching questions need to record Status: Currently in which a grid, how much gold has been spent, the current Can also use magic markers traveled grid so without any pruning to search can get. \ ( 55pts \) good results.

Plus a multi-optimality pruning you can get \ (10 pts \) .

Referred to a \ ([i] rem [j ] \) represents the \ ((1,1) \) to \ ((i, j) \ ) the minimum cost point of flowers, if we found here when the cost is greater than it is, then \ (return \) . not only does this pruning, but also remember a little \ (vis \) , so less maintenance \ (vis \) and can speed up.

\ (UPD \) : When do so and only if then come here when the price must be greater than the original case, but this problem is not necessarily the same color if there is a pair of rings, or die so the cycle continues?.

\ (Re UPD \) , according to the above fact, here is the practice, but the price must be greater than or equal time \ (return \) , and so must not remember \ (VIS \) .

Another point to note (especially if you want to maintain the VIS $ \ (the words): not the case with its excellent \) the DFS \ (better to go out again sentenced in ** \) before it is judged out dfs $ **.

\(Code\)

#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
#define yes(i,a,b) for(Ri i=a;i>=b;--i)
#define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define db double
#define inf 2147483647
using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
const int N=110;
int m,n,col[N][N],dx[4]={1,0,-1,0},dy[4]={0,1,0,-1},as=inf,rem[N][N];
il void dfs(Ri nx,Ri ny,Ri color,Ri sum,bool mag)
{
    if(sum>=as)return;
    if(nx==ny && nx==m){as=min(as,sum);return;}
    rem[nx][ny]=sum;
    go(i,0,3)
    {
        Ri tx=nx+dx[i],ty=ny+dy[i];
            if(tx<1 || tx>m || ty<1 || ty>m)continue;
    if(col[tx][ty])
    {
            if(col[tx][ty]==color && (rem[tx][ty]==-1 || sum<rem[tx][ty]))
            {dfs(tx,ty,col[tx][ty],sum,1);}
            else if(rem[tx][ty]==-1 || sum+1<rem[tx][ty])
            {dfs(tx,ty,col[tx][ty],sum+1,1);}
    }
    else if(mag && (rem[tx][ty]==-1 || sum<rem[tx][ty]))
    {dfs(tx,ty,color,sum+2,0);}
    }
}
int main()
{
    m=read(),n=read();mem(rem,-1);
    go(i,1,n){Ri x=read(),y=read(),c=read();col[x][y]=c+1;}
    dfs(1,1,col[1][1],0,1);
    if(as==inf)as=-1;
    printf("%d\n",as);
    return 0;
}

\ ([NOIp2017] \) hopscotch

\(Sol\)

First, determine whether the solution is to add up all the scores and \ (k \) comparison.

Sub-section is searchable, which will search out the grid in order to jump to get at least \ (k \) points, and statistics about the answer to it. This will get the \ (20pts \) .

I think we can \ (dp.jpg \) .

\ (f [i] [j ] \) before the representation \ (i \) grid, and choose the first \ (i \) grid, spend \ (j \) to improve the maximum value that can be obtained.

\(f[i][j]=max (f[k][g])+a[i],k<i\ 且\ abs(x[i]-x[k]-d)<=j且g<=j\).

Then \ (max (f [k] [g]) \) can be used here monotone bit queue optimization?

However, this is not enough to \ (AC \) has a problem, the time and space. If we can \ (f \) eliminates the need for one-dimensional like a. Not really, so to see the solution to a problem.

Comprehension solution after: In fact, the above \ (dp \) in the second dimension corresponds to enumerate minimum cost, minimum cost and should obviously be half so simple terms: First-half minimum cost, then the minimum cost \ ( dp \) , last statistical answer. \ (over \) .

\ (Written \)

Write code autistic, really I have to spell it in earnest to think again write the code acridine. Almost every time the code lightly, I feel like the time to write directly will be stuck for a long time, wrong everywhere, the actual time spent much more. Do not forget that you are a chicken dish ah! write code to be calm, cool, slow down.

\(Code\)

#include<bits/stdc++.h>
#define il inline
#define Ri register int
#define go(i,a,b) for(Ri i=a;i<=b;++i)
#define yes(i,a,b) for(Ri i=a;i>=b;--i)
#define e(i,u) for(Ri i=b[u];i;i=a[i].nt)
#define mem(a,b) memset(a,b,sizeof(a))
#define ll long long
#define inf 2147483647
using namespace std;
il int read()
{
    Ri x=0,y=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    return x*y;
}
const int N=500010;
int n,d,k,x[N],s[N],f[N],as=inf,L,R,mid,q[N];
il bool Ck()
{
    ll sum=0;Ri las=0;
    yes(i,n,1)if(s[i]>0){sum+=s[i];R=max(R,abs(x[i]-x[las]-d));las=i;};
    return (sum>=k);
}
il bool ck(Ri g)
{
    go(i,1,n)f[i]=-inf;f[0]=0;
    Ri l=1,r=0,las=0;
    go(i,1,n)
    {
        while(l<=r && x[q[l]]<x[i]-d-g)l++;
        while(las<=n && x[las]<x[i]-d-g)las++;
        while(las<i && x[las]<=x[i]-d+g )
        {
              if(f[las]==-inf){++las;continue;}
              while(l<=r && f[q[r]]<=f[las])r--;
             q[++r]=las;++las;
        }
        if(l<=r)f[i]=f[q[l]]+s[i];
        if(f[i]>=k)return 1;
    }
    return 0;
}
int main()
{
    n=read(),d=read(),k=read();
    go(i,1,n)x[i]=read(),s[i]=read();
    if(!Ck()){printf("-1\n");return 0;}
    while(L<=R)
    {
        mid=(L+R)>>1;
        if(ck(mid))as=mid,R=mid-1;
    }
    printf("%d\n",as);
    return 0;
}

\ ([NOIp2018] \) car ferry

Guess you like

Origin www.cnblogs.com/forward777/p/11664810.html