NOIP前刷水行动

Posted ACist

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOIP前刷水行动相关的知识,希望对你有一定的参考价值。

2016.11.15

BZOJ1009:DP+矩阵乘法+KMP

BZOJ1898:矩阵乘法

BZOJ4101:贪心,考虑我们往右边撞的时候,我们会向左边冲

      ,于是枚举答案点利用一个指针计算即可!

2016.11.14

OI队内测试

 

2016.11.13

BZOJ4512:乱搞

BZOJ4102:DP+bfs

BZOJ4395:bfs

BZOJ3889:双键值最短路

BZOJ4512

#include <bits/stdc++.h> 
using namespace std; 
#define LL long long 
int N,sx,sy,ans; 
char s[1020]; 
bool vis[2020][2020],north[2020][2020],east[2010][2010]; 
int main(){ 
//    freopen("data.in","r",stdin);
//    freopen("A.out","w",stdout);
    scanf("%d%s",&N,s); 
    sx=sy=1010; 
    for (int i=0;i<N;i++){ 
        vis[sx][sy]=1; 
        char ch=s[i]; 
        if (ch==\'N\'){ 
            sy++; 
            if (!north[sx][sy-1]&&vis[sx][sy])ans++; 
            north[sx][sy-1]=1; 
        } 
        if (ch==\'S\'){ 
            sy--; 
            if (!north[sx][sy]&&vis[sx][sy])ans++; 
            north[sx][sy]=1; 
        } 
        if (ch==\'E\'){ 
            sx++; 
            if (!east[sx-1][sy]&&vis[sx][sy])ans++; 
            east[sx-1][sy]=1; 
        } 
        if (ch==\'W\'){ 
            sx--; 
            if (!east[sx][sy]&&vis[sx][sy])ans++; 
            east[sx][sy]=1; 
        } 
    } 
    printf("%d\\n",ans); 
}

BZOJ4102

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define ll long long
#define ld long double
#define N 1005
#define M N*(N+1)
using namespace std;
int n,p,tot;
int pre[M],v[M],now[N],f[N],dis[N][N];
bool vis[N];
queue<int>q;
struct data{
    int val,pos;
}a[N];
int read()
{
    int x=0,f=1; char ch;
    while (ch=getchar(),ch<\'0\'||ch>\'9\') if (ch==\'-\') f=-1;
    while (x=x*10+ch-\'0\',ch=getchar(),ch>=\'0\'&&ch<=\'9\');
    return x*f;
}
void ins(int a,int b){++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b;
}
bool  cmp(data a,data b){return a.val<b.val;
}
void bfs(int u)
{
    memset(vis,0,sizeof(vis));
    q.push(u); dis[u][u]=0; vis[u]=1;
    while (!q.empty())
    {
        int x=q.front(); q.pop(); 
        for (int p=now[x]; p; p=pre[p])
        {
            int son=v[p]; 
            if (!vis[son])
            {
                dis[u][son]=dis[u][x]+1;
                q.push(son); vis[son]=1;
            }
        }
    }
}
int main()
{
    n=read(); p=read();
    for (int i=1; i<=n; i++)
    {
        int x=read(),d=read();
        a[i].val=x; a[i].pos=i; 
        for (int j=1; j<=d; j++) {int y=read(); ins(i,y); ins(y,i);}
    }
    for (int i=1; i<=n; i++) bfs(i);
    sort(a+1,a+n+1,cmp);
    for (int i=1; i<=n; i++) f[i]=a[i].val;
    for (int i=1; i<=n; i++)
        for (int j=1; j<=i-1; j++)
        {
            if (a[i].val>a[j].val && dis[a[i].pos][a[j].pos])
            {
                f[i]=max(f[i],f[j]-dis[a[i].pos][a[j].pos]*p+a[i].val);
            }
        }
    int ans=0;
    for (int i=1; i<=n; i++) ans=max(ans,f[i]);
    printf("%d\\n",ans);
    return 0;
}


BZOJ4395


#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define ll long long
#define ld long double
#define N 205
#define M 40005
using namespace std;
int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
int pre[M],v[M],now[N*N],tot;
int n,m,ans;
queue<int>q;
bool vis[N][N],lig[N][N];
int read()
{
    int x=0,f=1; char ch;
    while (ch=getchar(),ch<\'0\'||ch>\'9\') if (ch==\'-\') f=-1;
    while (x=x*10+ch-\'0\',ch=getchar(),ch>=\'0\'&&ch<=\'9\');
    return x*f;
}
int encode(int a,int b){return (a-1)*n+b;
}
void ins(int a,int b){
    ++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b;
}
int main()
{
    n=read(); m=read();
    for (int i=1; i<=m; i++)
    {
        int a=read(),b=read(),c=read(),d=read();
        ins(encode(a,b),encode(c,d));    
    }
    int last=1; ans=1;
    for (;;)
    {
        q.push(encode(1,1)); 
        memset(vis,0,sizeof(vis)); vis[1][1]=1; lig[1][1]=1;
        while (!q.empty())
        {
            int pp=q.front(),x,y; q.pop(); //last++;
            for (int p=now[pp]; p; p=pre[p])
            {
                int son=v[p]; x=(son-1)/n+1,y=(son-1)%n+1; 
                if (!lig[x][y]) lig[x][y]=1,ans++; 
            }
            x=(pp-1)/n+1,y=(pp-1)%n+1;
            for (int i=0; i<4; i++)
            {
                int xx=x+dx[i],yy=y+dy[i];
                if (xx<1 || xx>n || yy<1 || yy>n || !lig[xx][yy] || vis[xx][yy]) continue;
                vis[xx][yy]=1; q.push(encode(xx,yy));
            }
        }
        if (last==ans) break;
        last=ans;
    }
    printf("%d\\n",ans);
    return 0;
}


BZOJ3889

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define ll long long
#define ld long double
#define inf 100000000000000
#define N 1005
using namespace std;
int s,t,m,n;
ll a[N][N],b[N][N],dis[N],d[N];
int c[N];
bool vis[N];
queue<int>q;
int read()
{
    int x=0,f=1; char ch;
    while (ch=getchar(),ch<\'0\'||ch>\'9\') if (ch==\'-\') f=-1;
    while (x=x*10+ch-\'0\',ch=getchar(),ch>=\'0\'&&ch<=\'9\');
    return x*f;
}
void spfa()
{
    for (int i=1; i<=m; i++) dis[i]=inf;
    dis[s]=d[s]=0; vis[s]=1; q.push(s);
    while (!q.empty())
    {
        int x=q.front(); q.pop(); vis[x]=0;
        //cout<<"         "<<x<<endl;
        for (int i=1; i<=m; i++)
        {
        //    cout<<i<<" "<<dis[i]<<" "<<dis[x]<<" "<<a[x][i]<<endl;
            if (dis[i]>dis[x]+a[x][i] || ((dis[i]==dis[x]+a[x][i]) && d[i]>d[x]+b[x][i]))
            {
            //    cout<<"                "<<x<<" "<<i<<" "<<a[x][i]+dis[x]<<endl;
                dis[i]=dis[x]+a[x][i]; d[i]=d[x]+b[x][i];
                if (!vis[i]) vis[i]=1,q.push(i);
            }
        }    
        //|| (dis[i]==dis[x]+a[x][i] && d[i]>d[x]+b[x][i])
    }    
}
int main()
{
    s=read(); t=read(); n=read();
    for (int i=1; i<=1000; i++)    
        for (int j=1; j<=1000; j++) a[i][j]=inf;
    for (int i=1; i<=n; i++)
    {
        int len=read(),cnt=read();  
        for (int j=1; j<=cnt; j++) c[j]=read(),m=max(m,c[j]);
        for (int j=1; j<=cnt; j++)
            for (int k=j+1; k<=cnt; k++)
            if (a[c[j]][c[k]]>len || ((a[c[j]][c[k]]==len) && (b[c[j]][c[k]]>(k-j)))) a[c[j]][c[k]]=len,b[c[j]][c[k]]=k-j;
    }
    spfa();
    if (dis[t]==inf) dis[t]=-1,d[t]=-1;
    cout<<dis[t]<<" "<<d[t]<<endl;
    return 0;
}
View Code

 

2016.11.12

BZOJ3887: spfa(正边一次+反边一次)

BZOJ3886:状态压缩dp+二分(f[i]表示看电影状态为i的最长连续时间)

BZOJ4098:DP优化(f[i][j][k][l]:(i+j)==(k+l) 优化为f[i][j][k]:(i+j)满足滚动数组

BZOJ3888:把时间求出来+线段树

 

BZOJ3887

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define N 100005
#define M 200005
using namespace std;
int read()
{
    int x=0,f=1; char ch;
    while (ch=getchar(),ch<\'0\'||ch>\'9\') if (ch==\'-\') f=-1;
    while (x=x*10+ch-\'0\',ch=getchar(),ch>=\'0\'&&ch<=\'9\');
    return x*f;
}
int n,m;
int a[N],b[N];
int tot,pre[M],v[M],now[N];
int bel[N],low[N],dfn[N],num[N],total,ind,top,z[N];
int dist1[N],dist2[N];
bool inq[N],vis[N];
queue<int> q;
void ins(int a,int b){++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b;}
void tarjan(int x)
{
    low[x]=dfn[x]=++ind;
    ++top; z[top]=x; inq[x]=1;
    for (int p=now[x]; p; p=pre[p])
    {
        int son=v[p];
        if (!dfn[son]) tarjan(son),low[x]=min(low[x],low[son]);
        else if (inq[son]) low[x]=min(low[x],dfn[son]); 
    }
    if (low[x]==dfn[x])
    {
        ++total; num[total]=1; inq[x]=0; bel[x]=total;
        while (z[top]!=x)
        {
            int son=z[top]; bel[son]=total; inq[son]=0; num[total]++; top--;
        }
        top--;
    }
}
void build(int X)
{
    memset(now,0,sizeof(now)); tot=0;
    for (int i=1; i<=m; i++)
    {
        int x=a[i],y=b[i]; 
        if (bel[x]!=bel[y]) 
        {
            if (X==1) ins(bel[x],bel[y]); else ins(bel[y],bel[x]);
        }
    }
}
void spfa1()
{
    vis[bel[1]]=1; dist1[bel[1]]=num[bel[1]]; q.push(bel[1]);
    while (!q.empty())
    {
        int x=q.front(); q.pop(); vis[x]=0;
        for (int p=now[x]; p; p=pre[p])
        {
            int son=v[p];
            if (dist1[son]<dist1[x]+num[son]) 
            {
                dist1[son]=dist1[x]+num[son];
                if (!vis[son]) q.push(son),vis[son]=1;
            }
        }
    }
}
void spfa2()
{
    vis[bel[1]]=1; dist2[bel[1]]=num[bel[1]]; q.push(bel[1]);
    while (!q.empty())
    {
        int x=q.front(); q.pop(); vis[x]=0;
        for (int p=now[x]; p; p=pre[p])
        {
            int son=v[p];
            if (dist2[son]<dist2[x]+num[son]) 
            {
                dist2[son]=dist2[x]+num[son];
                if (!vis[son]) q.push(son),vis[son]=1;
            }
        }
    }
}
int main()
{
    n=read(); m=read();
    for (int i=1; i<=m; i++) a[i]=read(),b[i]=read(),ins(a[i],b[i]);
    for (int i=1; i<=n; i++) if (!dfn[i]) tarjan(i);
    build(1); spfa1();
    build(2); spfa2();
    int ans=0;
    for (int i=1; i<=m; i++) if (bel[a[i]]!=bel[b[i]] && dist1[bel[b[i]]] && dist2[bel[a[i]]]) 
    {
        ans=max(ans,dist1[bel[b[i]]]+dist2[bel[a[i]]]-num[bel[1]]);
    }
    printf("%d\\n",ans);
    return 0;
}

BZOJ3886


#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int n,L;
int num[25],len[25],c[25][1005];
int f[1100000];
int read()
{
    int x=0,f=1; char ch; 
    while (ch=getchar(),ch<\'0\'||ch>\'9\') if (ch==\'-\') f=-1;
    while (x=x*10+ch-\'0\',ch=getchar(),ch>=\'0\'&&ch<=\'9\');
    return x*f;
}
int find(int x,int s)
{
    int l=1,r=num[x],Ans=-1;
    while (l<=r)
    {
        int mid=(l+r)>>1;
        if (c[x][mid]<=s) Ans=mid,l=mid+1; else r=mid-1;
    }
    return Ans;
}
int main()
{
    n=read(); L=read();
    for (int i=1; i<=n; i++)
    {
        len[i]=read(); num[i]=read();
        for (int j=1; j<=num[i]; j++) c[i][j]=read();    
    } 
    f[0]=0;
    int s=1<<n,ans=0x7fffffff;
    for (int i=1; i<s; i++) f[i]=-1;
    for (int i=0; i<s; i++)
    {
        if (f[i]==-1) continue;
        int k=0;
        if (f[i]>L) 
        {
            for (int j=i; j; j>>=1) if (j&1) k++;
            ans=min(ans,k); continue;
        }
        for (int j=1; j<=n; j++)
        {
            if (i&(1<<(j-1))) continue;
            int k=find(j,f[i]); if (k==-1) continue;
            f[i|(1<<(j-1))]=max(f[i|(1<<(j-1))],c[j][k]+len[j]);
        }
    }
    if (ans==0x7fffffff) ans=-1;
    printf("%d\\n",ans);
    return 0;
}

BZOJ4098

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N 505
#define mod 1000000007
#define add(a,b) (a=(a+b)%mod)
using namespace std;
int n,f[2][N][N];
char s[N][N];
int main()
{
    scanf("%d",&n);
    for (int i=1; i<=n; i++) scanf("%s",s[i]+1);
    if(s[1][1]!=s[n][n])
    {
        puts("0");
        return 0;
    }
    int now=1,last=0;
    f[now][0][0]=1;
    for (int h=0; h<n; h++)
    {
        now^=1; last^=1;
        memset(f[now],0,sizeof(f[now]));
        for (int i=0; i<=h; i++)
        {
            int j=(h-i),a=i+1,b=j+1;
            for (int k=0; k<=h; k++)
            {
                int l=h-k,x=n-l,y=n-k;
            /*    if (s[a+1][b]==s[x][y-1]) (f[now][i+1][k+1]+=f[last][i][k])%mod;
                if (s[a+1][b]==s[x-1][y]) (f[now][i+1][k]+=f[last][i][k])%mod;
                if (s[a][b+1]==s[x][y-1]) (f[now][i][k+1]+=f[last][i][k])%mod;
                if (s[a][b+1]==s[x-1][y]) (f[now][i][k]+=f[last][i][k])%mod;    */ 
                if(s[a+1][b]==s[x-1][y])add(f[now][i+1][ k ],f[last][i][k]);
                if(s[a+1][b]==s[x][y-1])add(f[now][i+1][k+1],f[last][i][k]);
                if(s[a][b+1]==s[x-1][y])add(f[now][ i ][ k ],f[last][i][k]);
                if(s[a][b+1]==s[x][y-1])add(f[now][ i ][k+1],f[last][i][k]);
            } 
        }
    }
    int ans=0;
    for (int i=0; i<n; i++) add(ans,f[last][i][i]);
    printf("%d\\n",ans);
    return 0;
}

BZOJ3888

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N 50005
using namespace std;
int n,tot;
struct data{
    int h,l,r;
}a[N];
int b[2*N],cov[N*8];
int read()
{
    int x=0,f=1; char ch;
    while (ch=getchar(),ch<\'0\'||ch>\'9\') if (ch==\'-\') f=-1;
    while (x=x*10+ch-\'0\',ch=getchar(),ch>=\'0\'&&ch<=\'9\');
    return x*f;
}
bool cmp2(data a,data b){return a.h<b.h;
}
int get(int x,int c)
{
    return x>=0?0:-x*c;
}
int cover(int k,int l,int r,int x,int y)
{
    if (cov[k]) return 0;
    if (x<=l && r<=y)
    {
        cov[k]=1; return 1;
    }
    bool ret=0;
    int mid=(l+r)>>1;
    if (x<=mid) ret|=cover(k*2,l,mid,x,y);
    if (mid<y) ret|=cover(k*2+1,mid+1,r,x,y);
    cov[k]=cov[k*2]&cov[k*2+1];
    return特别行动队题解

几道莫名AC的并查集题

9.2NOIP模拟题

NOIP模拟赛10.07

刷水题

睡前刷8分钟手机,身体兴奋1小时