zoukankan      html  css  js  c++  java
  • 2017-10-23 NOIP模拟赛

    叉叉

    题目描述

    现在有一个字符串,每个字母出现的次数均为偶数。接下来我们把第一次出现的字母a和第二次出现的a连一条线,第三次出现的和四次出现的字母a连一条线,第五次出现的和六次出现的字母a连一条线...对其他25个字母也做同样的操作。

    现在我们想知道有多少对连线交叉。交叉的定义为一个连线的端点在另外一个连线的内部,另外一个端点在外部。

    下图是一个例子,共有三对连线交叉(我们连线的时候,只能从字符串上方经过)。

    输入格式

    一行一个字符串。保证字符串均由小写字母组成,且每个字母出现次数为偶数次。

    输出格式

    一个整数,表示答案。

    样例输入

    abaazooabz

    样例输出

    3

    数据范围

    对于30% 的数据,字符串长度不超过50。

    对于100% 的数据,字符串长度不超过100,000。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int top,ans,cnt[27],pos[27],num[27],a[100010];
    char s[100010];
    int main(){
        freopen("cross.in","r",stdin);freopen("cross.out","w",stdout);
        //freopen("Cola.txt","r",stdin);
        scanf("%s",s);
        int len=strlen(s);
        memset(pos,0x3f,sizeof(pos));
        for(int i=0;i<len;i++){
            int now=s[i]-'a';
            num[now]++;
            if(num[now]%2==0){
                ans+=cnt[now];
                for(int j=0;j<26;j++){
                    if(j==now)continue;
                    if(pos[j]<pos[now])cnt[j]--;
                }
                pos[now]=0x7fffffff;
                cnt[pos[now]]=0;
            }
            else {
                a[top]=now;
                pos[now]=top;
                cnt[now]=0;
                top++;
                for(int j=0;j<26;j++){
                    if(j==now)continue;
                    if(pos[j]<pos[now])cnt[j]++;
                }
            }
        }
        printf("%d",ans);
    }
    100分 栈模拟

     跳跳虎回家

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #define maxn 501
    using namespace std;
    int n,m,p,k,num,head[maxn],f[501][2001];
    struct node{int to,pre,v,mark;}e[2000+2001];
    struct Node{
        int id,cnt,dis;
        bool operator < (const Node b)const{
            return dis>b.dis;
        }
    };
    Node make_Node(int id,int cnt,int dis){
        Node res;
        res.id=id;res.cnt=cnt;res.dis=dis;
        return res;
    }
    void Insert(int from,int to,int v,int mark){
        e[++num].to=to;
        e[num].v=v;
        e[num].mark=mark;
        e[num].pre=head[from];
        head[from]=num;
    }
    priority_queue<Node>q;
    void Dij(){
        q.push(make_Node(1,0,0));
        memset(f,0x3f,sizeof(f));f[1][0]=0;
        while(!q.empty()){
            Node now=q.top();int point=now.id,d=now.dis,c=now.cnt;
            q.pop();
            for(int i=head[point];i;i=e[i].pre){
                int to=e[i].to;
                if(e[i].mark==0&&f[to][c]>f[point][c]+e[i].v){
                    f[to][c]=f[point][c]+e[i].v;
                    q.push(make_Node(to,c,f[to][c]));
                }
                if(c<k&&e[i].mark==1&&f[to][c+1]>f[point][c]+e[i].v){
                    f[to][c+1]=f[point][c]+e[i].v;
                    q.push(make_Node(to,c+1,f[to][c+1]));
                }
            }
        }
    }
    int main(){
        //freopen("Cola.in","r",stdin);
        freopen("move.in","r",stdin);freopen("move.out","w",stdout);
        scanf("%d%d%d%d",&n,&m,&p,&k);
        int x,y,z;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&z);
            Insert(x,y,z,0);
        }
        for(int i=1;i<=p;i++){
            scanf("%d%d%d",&x,&y,&z);
            Insert(x,y,z,1);
        }
        Dij();
        int ans=0x7fffffff;
        for(int i=0;i<=min(k,p);i++){
            ans=min(ans,f[n][i]);
        }
        if(ans>20000000){puts("-1");return 0;}
        printf("%d",ans);
    }
    80分 Dij+dp
    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #define maxn 5010
    using namespace std;
    int n,m,p,k,l,r,mid;
    int num,head[maxn],num2,head2[maxn],dis[maxn];
    bool vis[maxn],ok[maxn],flag;
    struct node{
        int to,pre,v,mark;
    }e[maxn],e2[maxn];
    void Insert(int from,int to,int v,int mark){
        e[++num].to=to;
        e[num].v=v;
        e[num].pre=head[from];
        e[num].mark=mark;
        head[from]=num;
    }
    void Insert2(int from,int to,int v,int mark){
        e2[++num2].to=to;
        e2[num2].v=v;
        e2[num2].pre=head2[from];
        e2[num2].mark=mark;
        head2[from]=num2;
    }
    void Spfa(){
        queue<int>q;
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        vis[1]=1;dis[1]=0;
        q.push(1);
        while(!q.empty()){
            int now=q.front();q.pop();vis[now]=0;
            for(int i=head[now];i;i=e[i].pre){
                if(e[i].mark)continue;
                int to=e[i].to;
                if(dis[to]>dis[now]+e[i].v){
                    dis[to]=dis[now]+e[i].v;
                    if(!vis[to])vis[to]=1,q.push(to);
                }
            }
        }
    }
    void dfs(int now,int d,int t){
        if(t>k)return;
        if(d>mid)return;
        if(now==n){flag=1;return;}
        if(flag)return;
        for(int i=head[now];i;i=e[i].pre){
            int to=e[i].to;
            if(!ok[to])continue;
            if(!vis[to]){
                vis[to]=1;
                dfs(to,d+e[i].v,t+e[i].mark);
                vis[to]=0;
            }
        }
    }
    bool check(){
        flag=0;
        memset(vis,0,sizeof(vis));
        vis[1]=1;
        dfs(1,0,0);
        if(flag)return 1;
        else return 0;
    }
    void bfs(){
        queue<int>q;
        q.push(n);ok[n]=1;
        while(!q.empty()){
            int now=q.front();q.pop();
            for(int i=head2[now];i;i=e2[i].pre){
                int to=e2[i].to;
                if(!ok[to]){
                    ok[to]=1;
                    q.push(to);
                }
            }
        }
    }
    int main(){
        //freopen("Cola.txt","r",stdin);
        freopen("move.in","r",stdin);freopen("move.out","w",stdout);
        scanf("%d%d%d%d",&n,&m,&p,&k);
        int x,y,z;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&z);
            Insert(x,y,z,0);
            Insert2(y,x,z,0);
            r+=z;
        }
        for(int j=1;j<=p;j++){
            scanf("%d%d%d",&x,&y,&z);
            Insert(x,y,z,1);
            Insert2(y,x,z,1);
            r+=z;
        }
        if(k==0){
            Spfa();
            if(dis[n]>=20000000){puts("-1");return 0;}
            printf("%d",dis[n]);return 0;
        }
        else {
            bfs();
            if(!ok[1]){puts("-1");return 0;}
            int ans=-1;
            while(l<=r){
                mid=(l+r)>>1;
                if(check())ans=mid,r=mid-1;
                else l=mid+1;
            }
            printf("%d",ans);
        }
    }
    95分 二分答案
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #define maxn 501
    using namespace std;
    int n,m,p,k,num,head[maxn],f[501][2001];
    bool vis[maxn][2001];
    struct node{int to,pre,v,mark;}e[2001+2001];
    struct Node{
        int id,cnt,dis;
        bool operator < (const Node b)const{
            return dis>b.dis;
        }
    };
    Node make_Node(int id,int cnt,int dis){
        Node res;
        res.id=id;res.cnt=cnt;res.dis=dis;
        return res;
    }
    void Insert(int from,int to,int v,int mark){
        e[++num].to=to;
        e[num].v=v;
        e[num].mark=mark;
        e[num].pre=head[from];
        head[from]=num;
    }
    priority_queue<Node>q;
    void Dij(){
        q.push(make_Node(1,0,0));
        memset(f,0x3f,sizeof(f));f[1][0]=0;
        while(!q.empty()){
            Node now=q.top();int point=now.id,d=now.dis,c=now.cnt;
            if(point==n)break;//非常有用的一句话 
            q.pop();
            for(int i=head[point];i;i=e[i].pre){
                int to=e[i].to;
                if(e[i].mark==0&&f[to][c]>f[point][c]+e[i].v){
                    f[to][c]=f[point][c]+e[i].v;
                    q.push(make_Node(to,c,f[to][c]));
                }
                if(c<k&&e[i].mark==1&&f[to][c+1]>f[point][c]+e[i].v){
                    f[to][c+1]=f[point][c]+e[i].v;
                    q.push(make_Node(to,c+1,f[to][c+1]));
                }
            }
        }
    }
    int main(){
        //freopen("Cola.in","r",stdin);
        freopen("move.in","r",stdin);freopen("move.out","w",stdout);
        scanf("%d%d%d%d",&n,&m,&p,&k);
        int x,y,z;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&z);
            Insert(x,y,z,0);
        }
        for(int i=1;i<=p;i++){
            scanf("%d%d%d",&x,&y,&z);
            Insert(x,y,z,1);
        }
        Dij();
        int ans=0x7fffffff;
        for(int i=0;i<=min(k,p);i++){
            ans=min(ans,f[n][i]);
        }
        if(ans>20000000){puts("-1");return 0;}
        printf("%d",ans);
    }
    100分 Dij+dp(一个有用的优化)

    秀秀和哺噜国

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define maxn 5010
    #define mod 786433
    using namespace std;
    int n,k,num,head[maxn],fal[maxn],sz[maxn],ans,can[maxn],c;
    bool vis[maxn],v[maxn];
    struct node{
        int to,pre,v;
    }e[maxn];
    void Insert(int from,int to,int id){
        e[id].to=to;
        e[id].pre=head[from];
        head[from]=id;
        num=max(num,id);
    }
    void Dfs(int now,int father){
        sz[now]=1;
        for(int i=head[now];i;i=e[i].pre){
            int to=e[i].to;
            if(to==father)continue;
            fal[to]=i;
            Dfs(to,now);
            sz[now]+=sz[to];
        }
    }
    int bfs(int x){
        int res=1;
        queue<int>q;
        q.push(x);
        vis[x]=1;
        while(!q.empty()){
            int now=q.front();q.pop();
            for(int i=head[now];i;i=e[i].pre){
                if(e[i].v!=0)continue;
                int to=e[i].to;
                if(!vis[to]){
                    vis[to]=1;
                    q.push(to);
                    res++;
                }
            }
        }
        return res;
    }
    bool check(){
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++){
            if(!vis[i]){
                if(bfs(i)<k)return 0;
            }
        }
        return 1;
    }
    void dfs(int pos){
        if(pos>c){
            //for(int i=1;i<=num;i++)cout<<i<<' '<<e[i].v<<endl;cout<<endl;
            if(check()){
                ans++;
                if(ans>=mod)ans-=mod;
            }
            return;
        }
        dfs(pos+1);
        int w=(can[pos]>=n?(can[pos]-n+1):(can[pos]+n-1));
        e[can[pos]].v=1;
        e[w].v=1;
        dfs(pos+1);
        e[can[pos]].v=0;
        e[w].v=0;
    }
    int main(){
        //freopen("Cola.in","r",stdin);
        freopen("cut.in","r",stdin);freopen("cut.out","w",stdout);
        scanf("%d%d",&n,&k);
        int x,y;
        for(int i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            Insert(x,y,i);Insert(y,x,i+n-1);
        }
        Dfs(1,0);
        int sum=0;
        for(int i=1;i<=n;i++)
            if(sz[i]<k){
                //e[fal[i]].v=1;
                int w=(fal[i]>=n?fal[i]-n+1:fal[i]+n-1);
                //e[w].v=1;
                v[fal[i]]=v[w]=1;
                sum++;
            }
        for(int i=1;i<=num;i++){
            if(v[i]==0){
                can[++c]=i;
                int w=(i>=n?i-n+1:i+n-1);
                v[w]=1;
                v[i]=1;
            }
        }
        dfs(1);
        printf("%d",ans);
        return 0;
    }
    20分 暴力
    #include<cstdio>
    #include<cstdlib>
    #define N 5555
    #define M 786433
    using namespace std;
    typedef long long LL;
    struct edge
    {
        int t,n;
    }e[N*2];
    LL h[N],size[N],f[N][N],g[N],cnt[N];
    int n,K,tote;
    void add(int u,int v)
    {
        e[++tote].t=v;
        e[tote].n=h[u];
        h[u]=tote;
        return ;
    }
    void dfs(int u,int fa)
    {
        size[u]++; f[u][1]=1;
        for (int i=h[u];i;i=e[i].n)
        {
            int v=e[i].t;
            if (v==fa) continue;
            dfs(v,u);
            for (int j=1;j<=size[u]+size[v];j++) g[j]=0;
            for (int j=1;j<=size[u];j++) g[j]=cnt[v]*f[u][j]%M;
            for (int j=1;j<=size[u];j++)
            for (int k=1;k<=size[v];k++) g[j+k]=(g[j+k]+f[u][j]*f[v][k]%M)%M;
            for (int j=1;j<=size[u]+size[v];j++) f[u][j]=g[j];
            size[u]+=size[v];
        }
        for (int i=K;i<=size[u];i++) cnt[u]=(cnt[u]+f[u][i])%M;
        return ;
    }
    int main()
    {
        freopen("cut.in","r",stdin);
        freopen("cut.out","w",stdout);
        scanf("%d %d",&n,&K);
        for (int i=1;i<n;i++)
        {
            int u,v;
            scanf("%d %d",&u,&v);
            add(u,v); add(v,u);
        }
        dfs(1,1);
        printf("%d
    ",cnt[1]);
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    100分 树形背包
  • 相关阅读:
    CSS的四种基本选择器和四种高级选择器
    Leetcode 897 递增顺序查找树
    Leetcode 872 叶子相似的树
    Leetcode 700 二叉搜索树中的搜索
    Leetcode 二叉树中第二小的节点
    Leetcode 669 修剪二叉搜索树
    Leetcode 653 两数之和IV
    Leetcode 637二叉树的层平均值
    Leetcode 617 合并二叉树
    Leetcode 606 根据二叉树创建字符串
  • 原文地址:https://www.cnblogs.com/thmyl/p/7716451.html
Copyright © 2011-2022 走看看