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分
原文地址:https://www.cnblogs.com/thmyl/p/7698612.html