zoukankan      html  css  js  c++  java
  • 2017 济南综合班 Day 6

    循环移动

    (cyclic.cpp/c/pas)

    (1s/256M)

    问题描述

    给出一个字符串SN个操作。每个操作用三元组(L, R, K)进行描述:操作将字符串第L个到第R个位置构成的子串循环移动K次。一次循环移动就是将字符串最后的这个字符移动到第一位,其余的字符顺次后移。

    例如,对于字符串abacaba,操作(L=3, R=6, K=1)后得到的字符串即为abbacaa

    求出在N个操作后得到的字符串。

    输入格式(cyclic.in)

    第一行一个字符串S

    第二行一个整数N,代表操作的总数。

    接下来N行每行三个数L,R,K,每行代表一个操作。

    输出格式(cyclic.out)

    一行一个字符串,代表N个操作后的字符串。

    样例输入

    abbacaa

    2

    3 6 1

    1 4 2

    样例输出

    ababaca

    数据范围与约束

    |S|为字符串S的长度。

    对于30%的数据,|S|<=100, N<=100, K<=100

    对于100%的数据,|S|<=10000, N<=300, K<=1000,000,1<=L<=R<=|S|

    #include<cstdio>
    #include<cstring>
    #define N 10010
    using namespace std;
    char s[N],tmp[N];
    int n,l,r,k,t,len;
    int main()
    {
        freopen("cyclic.in","r",stdin);
        freopen("cyclic.out","w",stdout);
        scanf("%s",s+1);
        len=strlen(s+1);
        scanf("%d",&n);
        while(n--)
        {
            scanf("%d%d%d",&l,&r,&k);
            k%=(r-l+1);
            if(!k) continue;
            t=l;
            for(int i=r-k+1;i<=r;i++) tmp[t++]=s[i];
            for(int i=l;i<=r-k;i++) tmp[t++]=s[i];
            for(int i=l;i<=r;i++) s[i]=tmp[i];
        }
        printf("%s",s+1);
    }
    View Code

    阅读计划

    (book.cpp/c/pas)

    (1s/256M)

    问题描述

    暑假到了,Rick制定了一个长达M天的阅读计划。他一共有N本书,从1N进行标号;Rick将它们从上至下摞成一堆。他每天都会读一本书,假设他要读编号为X的书,他会按照以下步骤:

    1. 将这本书上方的所有书搬起来

    2. 将这本书拿出来

    3. 将搬起来的书摞回去

    4. 看完后把这本书放到顶端

    每本书都会有各自的重量,Rick不希望搬起太过重的书。于是他希望能重新安排这N本书的顺序,使得读完M本书之后,搬书的重量之和最小。

    输入格式(book.in)

    第一行两个整数NM,分别代表书的数量和阅读的天数。

    第二行N个整数,代表每本书的重量。

    第三行M个整数,代表每天要读的书的编号。

    输出格式(book.out)

    一行一个整数,代表最小的重量之和。

    样例输入

    3 5

    1 2 3

    1 3 2 3 1

    样例输出

    12

    数据范围与约束

    对于30%的数据,N<=10.

    对于100%的数据,2<=N<=500, 1<=M<=1000, 每本书重量不超过100.

    00%的数据,|S|<=10000, N<=300, K<=1000,000,1<=L<=R<=|S|

    贪心:按书的第一次阅读顺序摆放

    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n,m,cnt,x,ans;
    int weight[501],read[1001];
    int first[501];
    bool v[501];
    int main()
    {
        freopen("book.in","r",stdin);
        freopen("book.out","w",stdout);    
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&weight[i]);
        for(int i=1;i<=m;i++) 
        {
            scanf("%d",&x);
            read[i]=x; 
            if(!first[x]) 
            {
                first[x]=i;
                ans+=cnt;
                cnt+=weight[x];
            }
        }
        for(int i=1;i<=m;i++)
            if(first[read[i]]!=i)
            {
                for(int j=i-1;j && read[j]!=read[i];j--) 
                  if(!v[read[j]]) ans+=weight[read[j]],v[read[j]]=true;
                memset(v,0,sizeof(v));
            }
        printf("%d",ans);
    }
    View Code

     

    树集

    (set.cpp/c/pas)

    (1s/256M)

    问题描述

    给出一棵N个节点的树,每个节点上都附有一个权值ai。现在Ann想从中选出若干个节点,满足以下条件:

    1. 至少选出一个节点

    2. 节点之间是连通的

    3. 设节点中权值最大的为ap最小的为aq,则需要满足ap-aq不大于某个定值D

    Ann想知道有多少种选择的方式?结果对1,000,000,007取模即可。

    输入格式(set.in)

    第一行包含两个整数D, N,分别代表定值D与节点总数N

    第二行包含N个整数ai,分别代表每个点的权值。

    接下来N-1行,每行包含两个数u, v,代表树中节点u与节点v是相连的。

    输出格式(set.out)

    一个整数,代表方案数模1,000,000,007的结果。

    样例输入

    1 4

    2 1 3 2

    1 2

    1 3

    3 4

    样例输出

    8

    样例解释

    8个选择方式为:{1}, {2}, {3}, {4}, {1, 2}, {1, 3}, {3, 4}, {1, 3, 4}

    数据范围与约束

    对于30% 的数据,1<=n<=10;

    对于另外的30% 的数据,d=2000.

    对于100% 的数据,0<=d<=2000, 1<=n<=2000, 1<=ai<=2000.

    树形DP,如何取消d的限制?

    枚举x作为选的点集中权值最小的点,

    那么可以选的点的点权范围:a[x]——a[x]+d

    小细节:如果点权相同,那么规定只能由编号小的走到编号大的

    #include<vector>
    #include<cstdio>
    #define N 2001
    #define mod 1000000007
    using namespace std;
    int d,n,l,r,ans,rt;
    int a[N],dp[N];
    vector<int>e[N];
    void dfs(int now,int last)
    {
        dp[now]=1;
        int siz=e[now].size();
        for(int i=0;i<siz;i++)
        {
            if(e[now][i]==last) continue;
            if(a[e[now][i]]<l || a[e[now][i]]>r || a[e[now][i]]==l&&e[now][i]<rt) continue;
            dfs(e[now][i],now);
            dp[now]=1ll*dp[now]*(dp[e[now][i]]+1)%mod;
        }
    }
    int main()
    {
        freopen("set.in","r",stdin);
        freopen("set.out","w",stdout);
        scanf("%d%d",&d,&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        int u,v;
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            e[u].push_back(v);
            e[v].push_back(u);
        }
        for(int i=1;i<=n;i++)
        {
            rt=i;
            l=a[i]; 
            r=a[i]+d;
            dfs(i,0);
            ans=(ans+dp[i])%mod;
        }
        printf("%d",ans);
    }
    View Code
  • 相关阅读:
    Linux Shell基础 单引号、双引号、反引号、小括号和大括号
    Linux Shell基础 通配符
    Linux Shell基础 管道符和grep命令
    Linux Shell基础 多个命令中的分号(;)、与(&&) 、 或(||)
    Linux Shell基础 Shell的输入重定向和输出重定向
    Linux Shell基础 Bash常见命令 history、alias命令以及常用快捷键
    Linux Shell基础 Bash常见命令 echo命令
    Linux Shell基础 Shell基本知识
    Linux文件系统管理 swap分区及作用
    《Hadoop权威指南 第4版》
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7391046.html
Copyright © 2011-2022 走看看