• 2017-10-4 清北刷题冲刺班a.m


    P101
    zhx


    a


    【问题描述】
    你是能看到第一题的 friends 呢。
    ——hja
    Hja 拥有一套时光穿梭技术,能把字符串以超越光速的速度传播,但是唯一
    的问题是可能会 GG。在传输的过程中,可能有四种情况:
    1、字符串没有发生改变。
    2、字符串的某一位由 0 变 1 或者由 1 变 0。
    3、某一位消失了。
    4、多了一位。
    为了防止字符串 GG,Hja 保证发送的字符串只由 01 组成,并且所有字符
    串开始的长度均为?,并且所有为 1 的位置的下标之和一定是? + 1的倍数。在
    给定了你这些条件之后,Hja 告诉你传输之后的字符串,并按照以下规则复原
    字符串:
    1、对于一个字符串,按照四种规则从前到后的优先级依次尝试能否复原为
    一个合法的字符串。
    2、对于同一种操作,更靠前的位置更加优先。
    3、对于同一种操作的同一位置,0 比 1 更加优先。
    4、如果没有任何一种方法复原字符串,则输出−1。
    【输入格式】
    第一行一个整数?,代表所有字符串的长度。
    接下来若干行,每行一个字符串。
    【输出格式】
    对于每个字符串,输出一行代表答案。
    【样例输入】
    4
    0000
    011
    1011
    11011
    【样例输出】
    0000
    0110
    1001
    1111
    【数据范围与规定】
    对于100%的数据,4 ≤ ? ≤ 1000,字符串数量不超过3000。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 100000
    using namespace std;
    int mod,pos[maxn],cnt,del[maxn],w[maxn],sum[maxn];
    string s;
    bool f;
    int n,len,l;
    void dfs(int len,int Sum,int t){
        if(f)return;
        if(len==n&&Sum%mod==0){
            for(int i=0;i<l;i++){
                if(del[i])continue;
                printf("%c",s[i]);
            }
            printf("
    ");
            f=1;
            return;
        }if(t)return;
        if(len==n)return;
        for(int i=0;i<l;i++){
            if(!del[i]){
                del[i]=1;
                if(s[i]=='0'){
                    dfs(len-1,Sum-w[i],1);if(f)return;
                }
                if(s[i]=='1'){
                    dfs(len-1,Sum-(i+1)-w[i+1],1);if(f)return;
                }
                del[i]=0;
            }
        }
    }
    void dfs1(int c,int Sum,int t){
        if(f)return;
        
        if(Sum%mod==0){
            cout<<s<<endl;
            f=1;
            return;
        }if(t)return;
        if(c==0)return;
        for(int i=1;i<=cnt;i++){
            if(!del[pos[i]-1]){
                del[pos[i]-1]=1;
                s[pos[i]-1]='0';
                dfs1(c-1,Sum-pos[i],1);
                del[pos[i]-1]=0;
                s[pos[i]-1]='1';
            }
        }
        
    }
    int main(){
        //freopen("Cola.txt","r",stdin);
        freopen("a.in","r",stdin);freopen("a.out","w",stdout);
        scanf("%d",&n);
        mod=n+1;
        while(cin>>s){
            memset(del,0,sizeof(del));
            memset(w,0,sizeof(w));
            f=0;
            cnt=0;
            l=len=s.length();
            int Sum=0;
            for(int i=0;i<len;i++)
                if(s[i]=='1'){
                    pos[++cnt]=i+1;
                    Sum+=i+1;
                }
            for(int i=l-1;i>=0;i--){
                if(s[i]=='1')w[i]=w[i+1]+1;
                else w[i]=w[i+1];
            }
            if(len==n){//一定是1,2操作 
                if(Sum%mod==0){
                    cout<<s<<endl;
                    continue;
                }
                bool flag=0;
                dfs1(cnt,Sum,0);
                if(!f) printf("-1
    ");
                continue;
            }
            if(len>n){//删掉几位 
                if(len-n>1){
                    printf("-1
    ");
                    continue;
                }
                f=0;
                dfs(len,Sum,0);
                if(!f)printf("-1
    ");
                continue;
            }
            if(len<n){//加上几位 
                if(n-len>1){
                    printf("-1
    ");
                    continue;
                }
                int num=0;
                for(int i=len-1;i>=0;i--){
                    if(s[i]=='1')    num+=i+1;
                    sum[i]=sum[i+1]+(s[i]=='1'?1:0);
                }
                int ans=num%(n+1),flag=0;
                for(int i=0;i<=len;i++){
                    if((sum[i]+ans)%(n+1)==0){
                        for(int j=0;j<len;j++)
                            if(j!=i)    cout<<s[j];
                            else if(i!=len)    cout<<"0"<<s[j];
                        if(i==len)    cout<<"0";
                        flag=1;
                        break;
                    }
                    if((sum[i]+ans+i+1)%(n+1)==0){
                        for(int j=0;j<len;j++)
                            if(j!=i)    cout<<s[j];
                            else if(i!=len)    cout<<"1"<<s[j];
                        if(i==len)    cout<<"1";
                        flag=1;
                        break;
                    }
                }
                if(!flag)    cout<<"-1";
                printf("
    ");
            }
        }
        fclose(stdin);fclose(stdout);
        return 0;
    }
    100分 模拟

    b


    【问题描述】
    你是能看到第二题的 friends 呢。
    ——laekov
    Hja 和 Yjq 在玩游戏,这个游戏中 Hja 给了 Yjq 两个数?,?,希望 Yjq 找到
    一些非负整数使得这些数的和等于?,并且所有数模?的值互不相同,求方案
    数。
    【输入格式】
    一行两个整数?,?。
    【输出格式】
    一行一个整数代表答案对905229641取模之后的结果。
    【样例输入 1】
    3 3
    【样例输出 1】
    9
    【样例输入 2】
    523 44
    【样例输出 2】
    338398304
    【数据范围与规定】
    220,? ≤ 5。
    4300,? ≤ 10。
    70%的数据,? ≤ 10 18 ,? ≤ 20。
    对于100%的数据,? ≤ 10 18 ,? ≤ 100。

    #include<iostream>
    #include<cstdio>
    #define mod 905229641
    using namespace std;
    long long n,limit,sm[500010];
    int m,ans;
    void dfs(int yu,long long res,int use){
        if(res==0){
            ans=(ans+sm[use])%mod;
            return;
        }
        if(yu==m)return;
        if(res<0)return;
        dfs(yu+1,res,use);
        for(int i=0;i<=limit;i++)
            dfs(yu+1,res-(i*m+yu),use+1);
    }
    int main(){
        //freopen("Cola.txt","r",stdin);
        freopen("b.in","r",stdin);freopen("b.out","w",stdout);
        sm[1]=1;
        for(int i=2;i<=500000;i++)sm[i]=sm[i-1]*i%mod;
        cin>>n>>m;
        limit=n/m;
        dfs(0,n,0);
        printf("%d",ans);
        fclose(stdin);fclose(stdout);
        return 0;
    }
    20分 暴力
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    #ifdef unix
    #define LL "%lld"
    #else
    #define LL "%I64d"
    #endif
    
    const int maxn=110;
    const int maxs=maxn*maxn/2;
    const int mo=905229641;
    
    long long n;
    
    int m,f[maxn][maxs],fac[maxn];
    
    int calc(long long a,long long b)
    {
        long long ans=1;
        for (int c=1;c<a;c++)
            ans=ans*(b+c)%mo;
        return (int)ans;
    }
    
    int main()
    {
        freopen("b.in","r",stdin);
        freopen("b.out","w",stdout);
    
        scanf(LL "%d",&n,&m);
        f[0][0]=1;
        int up=m*(m-1)/2;
        for (int a=0;a<m;a++)
            for (int b=m;b>=0;b--)
                for (int c=up;c>=0;c--)
                    if (f[b][c]) f[b+1][c+a]=(f[b+1][c+a]+f[b][c])%mo;
        fac[0]=1;
        for (int a=1;a<=m;a++)
            fac[a]=(long long)fac[a-1]*a%mo;
        int x=(int)(n%m);
        int ans=0;
        for (int a=x;a<=n && a<=up;a+=m)
        {
            long long rest=(n-a)/m;
            for (int b=1;b<=m;b++)
                if (f[b][a])
                {
                    int nowans=calc(b,rest%mo);
                    nowans=(long long)nowans*f[b][a]%mo;
                    nowans=(long long)nowans*b%mo;
                    ans=(ans+nowans)%mo;
                }
        }
        printf("%d
    ",ans);
    
        return 0;
    }
    100分

    c


    【问题描述】
    你是能看到第三题的 friends 呢。
    ——aoao
    Hja 回到老家开始种地,由于太久没有种地,所以所有地都是荒地。将每片
    地从荒地变成不荒地有一定的代价, 但是一旦改变之后就不再是荒地了。 现在Hja
    要开始?年的种地生活,第?年 Hja 可以在? ? 到? ? 块地上种地,并且可以获得? ? 的
    收益。 (注意,要种地必须整段一起种,并且这些地一定已经是不荒地)Hja 可以
    选择种或者不种每一年的地,问 Hja 能够获得的最大收益。
    【输入格式】
    第一行两个整数?,?,代表地的数量和年数。
    一行?个数,代表每块地变成不荒地的代价。
    接下来?行,每行三个整数? ? ,? ? ,? ? 如题意描述。
    【输出格式】
    一行一个整数代表答案。
    【样例输入】
    7 4
    3 2 3 2 1 2 3
    1 2 5
    2 3 5
    3 5 3
    7 7 5
    【样例输出】
    4
    【数据规模与约定】
    30%的数据,1 ≤ ?,? ≤ 100。
    对于100%的数据,1 ≤ ?,? ≤ 100000。

    #include<iostream>
    #include<cstdio>
    #define maxn 100010
    using namespace std;
    int n,m,w[maxn],ans=0,a[maxn*2],cnt;
    struct node{
        int l,r,v;
    }p[maxn];
    void dfs(int now,int sum){
        if(now==m+1){
            ans=max(ans,sum);
            return;
        }
        dfs(now+1,sum);
        int due=0;
        int pos=cnt+1;
        for(int i=p[now].l;i<=p[now].r;i++)due+=w[i],a[++cnt]=w[i],w[i]=0;
        dfs(now+1,sum-due+p[now].v);
        for(int i=p[now].l,j=pos;i<=p[now].r;i++,j++)w[i]=a[j];
        cnt=pos-1;
    }
    int main(){
        //freopen("Cola.txt","r",stdin);
        freopen("c.in","r",stdin);freopen("c.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d",&w[i]);
        for(int i=1;i<=m;i++)
            scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].v);
        dfs(1,0);
        cout<<ans;
        fclose(stdin);fclose(stdout);
        return 0;
    }
    10分 暴力
    #include <cstdio>
    #include <cctype>
    #include <memory.h>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long qw;
    
    #ifdef WIN32
    #define lld "%I64d"
    #else
    #define lld "%lld"
    #endif
    
    int nextInt() {
        int s = 0, d;
        bool nag = 0;
        do {
            d = getchar();
            if (d == '-')
                nag = 1;
        } while (!isdigit(d));
        do
            s = s * 10 + d - 48, d = getchar();
        while (isdigit(d));
        return nag ? -s : s;
    }
    
    struct seg {
        int l, r;
        qw v, z;
        seg *ls, *rs;
    };
    struct obj {
        int l, r, v;
    };
    
    inline bool cmpObj(const obj& a, const obj& b) {
        return (a. l < b. l) || (a. l == b. l && a. r < b. r);
    }
    
    const int maxn = 200009;
    const qw inf = 0x3f3f3f3f3f3f3f3fLL;
    
    int n, m;
    obj q[maxn];
    qw s[maxn], ans;
    seg *rtf, *rtc, *sp;
    
    #define mid(p) ((p->l+p->r)>>1)
    
    seg *sgtBuild(int l, int r) {
        seg *p = sp ++;
        p-> v = - inf;
        p-> z = 0;
        p-> l = l;
        p-> r = r;
        if (l + 1 < r) {
            p-> ls = sgtBuild(l, mid(p));
            p-> rs = sgtBuild(mid(p), r);
        }
        return p;
    }
    
    void sgtChg(seg* p, int p0, qw v0) {
        if (p-> l + 1 == p-> r)
            p-> v = max(p-> v, v0);
        else {
            if (p0 < mid(p))
                sgtChg(p-> ls, p0, v0 - p-> z);
            else
                sgtChg(p-> rs, p0, v0 - p-> z);
            p-> v = max(p-> ls-> v, p-> rs-> v) + p-> z;
        }
    }
    
    qw sgtQry(seg* p, int l, int r) {
        if (l >= r)
            return -inf;
        else if (p-> l == l && p-> r == r)
            return p-> v;
        else if (r <= mid(p))
            return sgtQry(p-> ls, l, r) + p-> z;
        else if (l >= mid(p))
            return sgtQry(p-> rs, l, r) + p-> z;
        else
            return max(sgtQry(p-> ls, l, mid(p)), sgtQry(p-> rs, mid(p), r)) + p-> z;
    }
    
    void sgtLazy(seg* p, int l, qw z0) {
        if (p-> v == -inf)
            return;
        else if (p-> l == l)
            p-> v += z0, p-> z += z0;
        else {
            if (l < mid(p)) {
                sgtLazy(p-> ls, l, z0);
                sgtLazy(p-> rs, mid(p), z0);
            }
            else
                sgtLazy(p-> rs, l, z0);
            p-> v = max(p-> ls-> v, p-> rs-> v) + p-> z;
        }
    }
    
    int main() {
        freopen("c.in","r",stdin);
        freopen("c.out","w",stdout);
        sp = new seg[maxn * 6];
        n = nextInt();
        m = nextInt();
        rtf = sgtBuild(0, n + 2);
        rtc = sgtBuild(0, n + 2);
        s[0] = 0;
        for (int i = 1; i <= n; i ++)
            s[i] = s[i - 1] + nextInt();
        for (int i = 0; i < m; i ++) {
            q[i]. l = nextInt();
            q[i]. r = nextInt();
            q[i]. v = nextInt();
        }
        sort(q, q + m, cmpObj);
        ans = 0;
        for (int i = 0; i < m; i ++) {
            qw res0 = max(sgtQry(rtf, 0, q[i]. l), 0LL) - s[q[i]. r] + s[q[i]. l - 1];
            qw res1 = sgtQry(rtc, q[i]. l, q[i]. r + 1) - s[q[i]. r];
            qw res = max(max(res0, res1), sgtQry(rtf, q[i]. r, n + 1)) + q[i]. v;
            sgtLazy(rtf, q[i]. r, q[i]. v);
            sgtLazy(rtc, q[i]. r, q[i]. v);
            sgtChg(rtf, q[i]. r, res);
            sgtChg(rtc, q[i]. r, res + s[q[i]. r]);
            ans = max(ans, res);
        }
        printf(lld "
    ", ans);
    }
    100分
  • 相关阅读:
    linux分区-df
    day34 协程
    day33 GIL锁 线程队列 线程池
    day32 线程
    day31 管道 进程池 数据共享
    day30 锁 队列
    day29 进程
    day28 socketserver
    day27 粘包及粘包的解决方案
    day26 网络通讯的整个流程
  • 原文地址:https://www.cnblogs.com/thmyl/p/7625379.html
Copyright © 2020-2023  润新知