• 2017-10-20 NOIP模拟赛


    Lucky Transformation

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int n,k,cnt;
    char s[1000010];
    int main(){
        freopen("trans.in","r",stdin);freopen("trans.out","w",stdout);
        //freopen("Cola.txt","r",stdin);
        while(scanf("%d%d",&n,&k)!=EOF){
            scanf("%s",s);cnt=0;
            int rest=0;
            for(int i=0;i<n;i++){
                if(s[i]=='2'&&s[i+1]=='3'){
                    if(i>0&&(i+1)%2==0&&s[i-1]=='2'&&s[i+1]=='3'){
                        rest=k-cnt;break;
                    }
                    else if((i+1)%2==1&&s[i+1]=='3'&&s[i+2]=='3'){
                        rest=k-cnt;break;
                    }
                    else{
                        if((i+1)%2==0)s[i]='3';
                        else s[i+1]='2';
                        cnt++;
                        if(cnt==k)break;
                    }
                }
            }
            rest%=2;
            if(rest==0||cnt==k){
                printf("%s
    ",s);
            }
            else{
                for(int i=0;i<n;i++){
                    if(s[i]=='2'&&s[i+1]=='3'){
                        if((i+1)%2==0)s[i]='3';
                        else s[i+1]='2';
                        break;
                    }
                }
                printf("%s
    ",s);
            }
        }
    }
    100分 规律

    Snake vs Block

    #include<iostream>
    #include<cstdio>
    #define maxn 210
    using namespace std;
    int n,m,map[maxn][7],num,ans,head[maxn],edge[maxn*6+10][maxn*6+10];
    struct node{
        int to,pre,v;
    }e[maxn*7*3];
    int make_id(int i,int j){return (i-1)*5+j;}
    void Insert(int from,int to,int v){
        e[++num].to=to;
        e[num].v=v;
        e[num].pre=head[from];
        head[from]=num;
        edge[from][to]=num;
    }
    void dfs(int x,int y,int sc,int len){
        if(x>n){
            ans=max(ans,sc);
            return;
        }
        int now=make_id(x,y);
        for(int i=head[now];i;i=e[i].pre){
            int to=e[i].to;
            if(e[i].v==0)continue;
            int xx=(to-1)/5+1,yy=to%5;
            if(yy==0)yy=5;
            e[i].v=0;
            if(map[xx][yy]>=0){
                int p=map[xx][yy];
                map[xx][yy]=0;
                dfs(xx,yy,sc,len+p);
                map[xx][yy]=p;
            }
            else {
                if(len+map[xx][yy]<0){ans=max(ans,sc);}
                else {
                    int p=map[xx][yy];
                    map[xx][yy]=0;
                    dfs(xx,yy,sc-p,len+p);
                    map[xx][yy]=p;
                }
            }
            e[i].v=1;
        }
    }
    int main(){
        freopen("snakevsblock.in","r",stdin);freopen("snakevsblock.out","w",stdout);
        //freopen("Cola.txt","r",stdin);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=5;j++){
                int id=make_id(i,j);
                if(j!=1)Insert(id,make_id(i,j-1),1);//向左
                if(j!=5)Insert(id,make_id(i,j+1),1);//向右 
                Insert(id,make_id(i+1,j),1);//向下 
                scanf("%d",&map[i][j]);
            }
        scanf("%d",&m);
        int x,y;
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            int id1=make_id(x,y),id2=make_id(x,y+1);
            e[edge[id1][id2]].v=0;
            e[edge[id2][id1]].v=0;
        }
        dfs(1,3,0,4);
        printf("%d",ans);
    }
    30分 建图+dfs
    /*
    把豆豆和砖块丢在一起dp 
    f[i][j][k]:到第i行,蛇的长度还剩下j,从k位置出第i行的最大得分 
    g[j][l][r]:蛇的长度剩下j,从当前行l到r区间内仍为死亡的最大得分 
    初始化:对于每个i,g[j][k][k]=f[i-1][j-a[i][k]][k]+max(-a[i][k],0) 为初始状态 
    方程g[j][l][r] = max(g[j-a[i][l]][l+1][r] + max(-a[i][j],0),g[j-a[i][r]][l][r-1]+max(-a[i][k],0)); 
    最后f[i][j][k] = max{g[j][l][r](1≤l≤k ≤r ≤5)} 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    #define N 207
    #define M 10005
    
    using namespace std;
    int a[N][5],f[N][M][5],g[M][5][5];
    bool flag[N][4];
    int n,m,maxi,ans,val;
    
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    int main()
    {
        freopen("snakevsblock.in","r",stdin);
        freopen("snakevsblock.out","w",stdout);
        n=read();int x,y;
        for(int i=1;i<=n;i++) for(int j=0;j<5;j++)
          a[i][j]=read();
        m=read();
        for(int i=1;i<=m;i++)
        {
            x=read();y=read();
            flag[x][y-1]=1;
        }
        memset(f,-0x7f7f7f,sizeof f);
        f[0][4][2]=0;maxi=n*50;
        
        for(int i=1;i<=n;i++)
        {
            memset(g,-0x7f7f7f,sizeof g);
            for(int j=0;j<=maxi;j++)
              for(int k=0;k<5;k++)
                if(j-a[i][k]>=0 && j-a[i][k]<=maxi)
                  f[i][j][k]=g[j][k][k]=f[i-1][j-a[i][k]][k]+max(-a[i][k],0);
    
            for(int l=1;l<=4;l++)
              for(int j=0,k=j+l;k<5;j++,k++)
                for(int v=0;v<=maxi;v++)
                {
                    if(!flag[i][j]  && (val=v-a[i][j])>=0 && val<=maxi) g[v][j][k] = g[val][j + 1][k] + max(-a[i][j], 0);//g[v][j][k]=max(g[v][j][k],g[val][j+1][k]+max(-a[i][j],0));
                    if(!flag[i][k-1]&& (val=v-a[i][k])>=0 && val<=maxi) g[v][j][k]=max(g[v][j][k],g[val][j][k-1]+max(-a[i][k],0));
                    for(int to=j;to<=k;to++) f[i][v][to]=max(f[i][v][to],g[v][j][k]);
                }
        }
        
        for(int i=0;i<=n;i++)
          for(int j=0;j<=maxi;j++)
            for(int k=0;k<5;k++)
              ans=max(f[i][j][k],ans);
              
        printf("%d
    ",ans);
        return 0;
    }
    100分 动态规划

    Ping

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define maxn 100010
    using namespace std;
    int n,m,k,num,head[maxn],fa[maxn],dep[maxn],h[maxn],cnt;
    bool vis[maxn],v[maxn];
    int c[16][1<<15];
    struct node{
        int to,pre;
    }e[maxn*2];
    struct Node{
        int l,r;
    }p[300010];
    void Insert(int from,int to){
        e[++num].to=to;
        e[num].pre=head[from];
        head[from]=num;
    }
    int count(int x){
        int res=0;
        while(x){
            if(x&1)res++;
            x>>=1;
        }
        return res;
    }
    void dfs(int now,int father){
        fa[now]=father;dep[now]=dep[father]+1;
        for(int i=head[now];i;i=e[i].pre){
            int to=e[i].to;
            if(to==father)continue;
            dfs(to,now);
        }
    }
    int sta;
    bool lca(int a,int b){
        if(vis[a]||vis[b])return 1;
        if(dep[a]<dep[b])swap(a,b);
        while(dep[a]>dep[b]){
            a=fa[a];
            if(vis[a])return 1;
        }
        while(a!=b){
            a=fa[a];b=fa[b];
            if(vis[a]||vis[b])return 1;
        }
        return 0;
    }
    bool ok(int s){
        memset(vis,0,sizeof(vis));
        int pos=0;
        while(s){
            pos++;
            if(s&1)vis[h[pos]]=1;
            s>>=1;
        }
        for(int i=1;i<=k;i++){
            int a=p[i].l,b=p[i].r;
            if(lca(a,b))continue;
            else return 0;
        }
        return 1;
    }
    bool check(int x){
        for(int i=1;i<=c[x][0];i++){
            int s=c[x][i];
            if(ok(s)){
                sta=s;
                return 1;
            }
        }
        return 0;
    }
    int main(){
        freopen("ping.in","r",stdin);freopen("ping.out","w",stdout);
        //freopen("Cola.txt","r",stdin);
        scanf("%d%d",&n,&m);
        for(int i=0;i<=(1<<n)-1;i++){
            int nu=count(i);
            c[nu][++c[nu][0]]=i;
        }
        int x,y;
        for(int i=1;i<=m;i++){
            scanf("%d%d",&x,&y);
            Insert(x,y);Insert(y,x);
            if(!v[x])h[++cnt]=x,v[x]=1;
            if(!v[y])h[++cnt]=y,v[y]=1;
        }
        dfs(1,1);
        scanf("%d",&k);
        for(int i=1;i<=k;i++)
            scanf("%d%d",&p[i].l,&p[i].r);
        int l=1,r=cnt,ans=0;
        while(l<=r){
            int mid=(l+r)>>1;
            if(check(mid))ans=mid,r=mid-1;
            else l=mid+1;
        }
        printf("%d
    ",ans);
        int pos=0;
        while(sta){
            pos++;
            if(sta&1)printf("%d ",h[pos]);
            sta>>=1;
        }
        return 0;
    }
    30分 二分答案
    #include <bits/stdc++.h>
    using namespace std;
    int n, m, P, u, v, to[200005], nxt[200005], p[100005], deep[100005], q[500005][2];
    int son[100005], fa[100005], size[100005], top[100005], dfsx[100005], cnt, ans;
    int lca[500005], Q[500005], lr[100005][2];
    int sta[100005];
    bool flag[400005];
    void dfs(int x)
    {
        size[x] = 1;
        for (int i = p[x]; i != -1; i = nxt[i])
            if (to[i] != fa[x])
            {
                fa[to[i]] = x;
                deep[to[i]] = deep[x] + 1;
                dfs(to[i]);
                if (son[x] == -1 || size[to[i]] > size[son[x]]) son[x] = to[i];
                size[x] += size[to[i]];
            }
    }
    void dfs1(int x)
    {
        dfsx[x] = ++cnt;
        if (son[x] != -1) top[son[x]] = top[x], dfs1(son[x]);
        for (int i = p[x]; i != -1; i = nxt[i])
            if (to[i] != fa[x] && to[i] != son[x])
                top[to[i]] = to[i], dfs1(to[i]);
    }
    int findlca(int x, int y)
    {
        while (1)
        {
            if (top[x] == top[y]) return deep[x] > deep[y]? y : x;
            if (deep[top[x]] > deep[top[y]]) x = fa[top[x]];
            else y = fa[top[y]];
        }
    }
    bool query(int x, int l, int r, int ll, int rr)
    {
        if (l == ll && r == rr) return flag[x];
        int mid = (l + r) >> 1, L = x << 1, R = L | 1;
        if (rr <= mid) return query(L, l, mid, ll, rr);
        else if (ll > mid) return query(R, mid + 1, r, ll, rr);
        else return query(L, l, mid, ll, mid) | query(R, mid + 1, r, mid + 1, rr);
    }
    void modify(int x, int l, int r, int to)
    {
        flag[x] = true;
        if (l == r) return;
        int mid = (l + r) >> 1, L = x << 1, R = L | 1;
        if (to <= mid) modify(L, l, mid, to);
        else modify(R, mid + 1, r, to);
    }
    bool Query(int x, int y)
    {
        while (1)
        {
            if (top[x] == top[y])
            {
                if (deep[x] < deep[y]) return query(1, 1, cnt, dfsx[x], dfsx[y]);
                else return query(1, 1, cnt, dfsx[y], dfsx[x]);
            }
            if (deep[top[x]] > deep[top[y]])
                if (query(1, 1, cnt, dfsx[top[x]], dfsx[x])) return true;
                else x = fa[top[x]];
            else
            {
                if (query(1, 1, cnt, dfsx[top[y]], dfsx[y])) return true;
                else y = fa[top[y]];
            }
        }
    }
    void work(int x)
    {
        for (int i = p[x]; i != -1; i = nxt[i])
            if (to[i] != fa[x])
                work(to[i]);
        for (int i = lr[x][0]; i <= lr[x][1]; i++)
            if (!Query(q[Q[i]][0], q[Q[i]][1]))
            {
                modify(1, 1, cnt, dfsx[x]);
                sta[++ans] = x;
                return;
            }
    }
    bool cmp(int x, int y) {return lca[x] < lca[y];}
    int main()
    {
        freopen("ping.in","r",stdin);
        freopen("ping.out","w",stdout);
        scanf("%d%d", &n, &m);
        for (int i = 0; i <= n; i++) p[i] = son[i] = -1, top[i] = size[i] = fa[i] = deep[i] = 0;
        for (int i = 1; i <= n * 4; i++) flag[i] = false;
        for (int i = 1; i <= m; i++)
        {
            scanf("%d%d", &u, &v);
            u--, v--;
            to[i * 2 - 1] = v;
            nxt[i * 2 - 1] = p[u];
            p[u] = i * 2 - 1;
            to[i * 2] = u;
            nxt[i * 2] = p[v];
            p[v] = i * 2;
        }
        deep[0] = 1;
        dfs(0);
        cnt = 0;
        dfs1(0);
        scanf("%d", &P);
        for (int i = 1; i <= P; i++)
        {
            scanf("%d%d", &u, &v);
            u--, v--;
            q[i][0] = u, q[i][1] = v;
            lca[i] = findlca(u, v);
            Q[i] = i;
        }
        sort(Q + 1, Q + P + 1, cmp);
        for (int i = 0; i <= n; i++) lr[i][0] = P + 1, lr[i][1] = 0;
        for (int i = 1; i <= P; i++)
        {
            lr[lca[Q[i]]][0] = min(lr[lca[Q[i]]][0], i);
            lr[lca[Q[i]]][1] = max(lr[lca[Q[i]]][1], i);
        }
        ans = 0;
        work(0);
        printf("%d
    ", ans);
        for (int i = 1; i <= ans; i++) printf("%d ", sta[i] + 1);
        return 0;
    }
    100分
  • 相关阅读:
    【leetcode】1020. Partition Array Into Three Parts With Equal Sum
    【leetcode】572. Subtree of Another Tree
    【leetcode】123. Best Time to Buy and Sell Stock III
    【leetcode】309. Best Time to Buy and Sell Stock with Cooldown
    【leetcode】714. Best Time to Buy and Sell Stock with Transaction Fee
    【leetcode】467. Unique Substrings in Wraparound String
    【leetcode】823. Binary Trees With Factors
    【leetcode】143. Reorder List
    【leetcode】1014. Capacity To Ship Packages Within D Days
    【leetcode】1013. Pairs of Songs With Total Durations Divisible by 60
  • 原文地址:https://www.cnblogs.com/thmyl/p/7698612.html
Copyright © 2020-2023  润新知