zoukankan      html  css  js  c++  java
  • UVa 714

    题目链接:714 - Copying Books

    解题思路

    具体处理方法见代码

    /**************************************************************
        Problem:
        User: youmi
        Language: C++
        Result: Accepted
        Time:
        Memory:
    ****************************************************************/
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    //#include<bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <stack>
    #include <set>
    #include <sstream>
    #include <cmath>
    #include <queue>
    #include <string>
    #include <vector>
    #define zeros(a) memset(a,0,sizeof(a))
    #define ones(a) memset(a,-1,sizeof(a))
    #define sc(a) scanf("%d",&a)
    #define sc2(a,b) scanf("%d%d",&a,&b)
    #define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
    #define scs(a) scanf("%s",a)
    #define sclld(a) scanf("%I64d",&a)
    #define pt(a) printf("%d
    ",a)
    #define ptlld(a) printf("%I64d
    ",a)
    #define rep0(i,n) for(int i=0;i<n;i++)
    #define rep1(i,n) for(int i=1;i<=n;i++)
    #define rep_1(i,n) for(int i=n;i>=1;i--)
    #define rep_0(i,n) for(int i=n-1;i>=0;i--)
    #define Max(a,b) (a)>(b)?(a):(b)
    #define Min(a,b) (a)<(b)?(a):(b)
    #define lson (step<<1)
    #define rson (lson+1)
    #define esp 1e-6
    #define oo 0x3fffffff
    #define TEST cout<<"*************************"<<endl
    
    using namespace std;
    typedef long long ll;
    
    int n,k;
    
    const int maxn=500+10;
    ll a[maxn];
    map<int,int>m;//用来标记1-n哪些位置应该有“/”符号的
    int main()
    {
        //freopen("in.txt","r",stdin);
        int T_T;
        scanf("%d",&T_T);
        for(int kase=1;kase<=T_T;kase++)
        {
            sc2(n,k);
            ll l=0,r=0;
            rep1(i,n)
            {
                sclld(a[i]);
                l=Max(l,a[i]);//二分下限肯定是最大值
                r+=a[i];//上限自然是所有的总和
            }
            int tot=0;
            ll cur=r;
            ll temp;
            while(l<r)//每种方法都有其区块和的最大值,比如白皮书说的7,9.所以我们二分找满足分块条件的最大区块和当中的最小值
            {//比如白皮书上的案例,7<9,所以我们找到了7
                tot=0;
                temp=0;
                //printf("l->%I64d cur->%I64d r->%I64d
    ",l,cur,r);
                for(int i=n;i>=1;i--)//从末尾开始统计(其实这里从头开始也可以,因为我们是找最小的分块条件),每次都贪心使后面的越大,那么前面的自然就越小了
                {
                    //printf("tot->%d temp->%I64d 
    ",tot,temp);
                    temp+=a[i];
                    if(temp>cur)
                    {
                        ++tot;
                        i++;//因为temp加上a[i]就超过了cur,所以我们下一块的最右边应该是a[i],所以这里i++与for循环里的i--抵消
                        //printf("%d %d %I64d
    ",tot,i-1,temp-a[i-1]);
                        temp=0;
                        if(tot==k)//分了k次,那么总共有k+1块,也就是说这种情况下cur太小了
                        {
                            l=cur+1;
                            cur=(l+r)>>1;
                            break;
                        }
                    }
                }
                if(tot<k)//用cur分块结果分的块不够多,比如可能只分了一块,所以这种情况cur太大了
                {
                    r=cur;
                    cur=(l+r)>>1;
                }
            }//while循环后,我们找到了一个最小的满足分块条件的区块和最大值,当前cur值即为该值,然后贪心从后面开始来
                tot=0;
                temp=0;
                m.clear();
                for(int i=n;i>=1;i--)
                {
                    temp+=a[i];
                    if(temp>cur)
                    {
                        m[i++]=1;
                        ++tot;
                        temp=0;
                    }
                }
            k--;
            int id=1;
            while(tot<k)//如果按cur分的块数少于cur,比如100,100,100,100,100,这种情况,分4块则cur最小满足条件应该是200,按200从后分,得到100/100 100/100 100,分少了
            {//那么我们在100/100 100/100 100中随便插一块板也是满足条件的,为了使前面尽量少,所以我应该把板插前面,因此从1开始搜索
                if(!m[id])
                {
                    m[id]=1;
                    tot++;
                }
                id++;
            }
            //ptlld(r);
            rep1(i,n)
            {
                printf("%lld%c",a[i],i==n?'
    ':' ');
                if(m[i])
                {
                    printf("/ ");
                }
            }
        }
        return 0;
    }
    不为失败找借口,只为成功找方法
  • 相关阅读:
    CB文件读入后输出中文乱码问题
    2019-ICPC-沈阳站打铁感想
    计蒜客习题:画图游戏(Havel-Hakimi定理)
    计蒜客练习题:接龙(带权并查集)
    搜索----Dungeon Master
    最短路 poj1502 MPI Maelstrom
    poj 3259 Wormholes
    Silver Cow Party
    Til the Cows Come Home
    Cow Contest
  • 原文地址:https://www.cnblogs.com/youmi/p/4734308.html
Copyright © 2011-2022 走看看