2016 CCPC Hangzhou Onsite A - ArcSoft's Office Rearrangement(HDU 5933) (贪心,模拟)


ArcSoft, Inc. is a leading global professional computer photography and computer vision technology company. 

There are  N N working blocks in ArcSoft company, which form a straight line. The CEO of ArcSoft thinks that every block should have equal number of employees, so he wants to re-arrange the current blocks into  K K new blocks by the following two operations: 

- merge two neighbor blocks into a new block, and the new block's size is the sum of two old blocks'. 
- split one block into two new blocks, and you can assign the size of each block, but the sum should be equal to the old block. 

Now the CEO wants to know the  minimum operations to re-arrange current blocks into  K Kblock with equal size, please help him.
Input
First line contains an integer  T T, which indicates the number of test cases. 

Every test case begins with one line which two integers  N N and  K K, which is the number of old blocks and new blocks. 

The second line contains  N N numbers  a1 a1 a2 a2 aN aN, indicating the size of current blocks. 

Limits 
1T100 1≤T≤100 
1N105 1≤N≤105 
1K105 1≤K≤105 
1ai105 1≤ai≤105
Output
For every test case, you should output  'Case #x: y', where  x indicates the case number and counts from  1 and  y is the minimum operations. 

If the CEO can't re-arrange  K K new blocks with equal size,  y equals  -1.
Sample Input
3
1 3
14
3 1
2 3 4
3 6
1 2 3
Sample Output
Case #1: -1
Case #2: 2
Case #3: 3

123


【体会】

 

第一道 题,   这道题, 感觉自己真的要被 逼疯了,   组队赛时,  我敲的  一直WA     直到现在 我也没有发现  WA 在哪里,  思路 完全是正确的;

赛后, 我从百度 拿到正确代码, 用Shell 脚本 随机生成 1000多组数据  测试 用我的 代码 同 正确代码 比较

mmp   一模一样,  我不想说什么了  

 发一下 自己 WA的代码  如果有人看到,  看出BUG  请 赐教 !!


【思路】

只有两个 方式 合并 拆分,  并且是 相邻的 

那么 就从 第一项开始,  如果比平均大  则 减  若 小 则加后面的项, 相同不管;

我的思路 是 用  k的数量 来控制

给 n,k  如果可以, 那么一定能够 形成新的 k个数 因此 用k 来控制 

【正确代码】

//#include <bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN      freopen("input.txt","r",stdin)
#define FOUT     freopen("output.txt","w",stdout)
#define S1(n)    scanf("%d",&n)
#define SL1(n)   scanf("%I64d",&n)
#define S2(n,m)  scanf("%d%d",&n,&m)
#define SL2(n,m)  scanf("%I64d%I64d",&n,&m)
#define Pr(n)     printf("%d\n",n)
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r

using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int MAXN=100005;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};

ll inv[maxn*2];
inline void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){ x=1; y=0; d=a; }else{ ex_gcd(b,a%b,d,y,x); y-=x*(a/b);};}
inline ll gcd(ll a,ll b){ return b?gcd(b,a%b):a;}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll ans=exgcd(b,a%b,x,y);ll temp=x;x=y;y=temp-a/b*y;return ans;}
inline ll lcm(ll a,ll b){ return b/gcd(a,b)*a;}
inline ll qpow(ll x,ll n){ll res=1;for(;n;n>>=1){if(n&1)res=(res*x)%MOD;x=(x*x)%MOD;}return res;}
inline ll inv_exgcd(ll a,ll n){ll d,x,y;ex_gcd(a,n,d,x,y);return d==1?(x+n)%n:-1;}
inline ll inv1(ll b){return b==1?1:(MOD-MOD/b)*inv1(MOD%b)%MOD;}
inline ll inv2(ll b){return qpow(b,MOD-2);}

ll a[maxn];
int main()
{
    int t;
    int n,k;
    int cont=0;
    cin>>t;
    while(t--)
    {
        mem(a,0);
        scanf("%d %d",&n,&k);
        ll sum=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            sum+=a[i];
        }
        printf("Case #%d: ",++cont);
        if(sum%k!=0)
        {
            printf("-1\n");
            continue;
        }
        ll t=sum/k;
        ll last=a[1];
        int i=1;
        ll ans=0;
        ll cot=0;
        while(cot<k)
        {
            if(last>t)
            {
                last=last-t;
                ans++;
                cot++;
            }
            else if(last<t)
            {
				last +=a[++i];
				ans++;
            }
            else 
            {
                last=a[++i];
                cot++;
            }
        }
       // printf("%d %d  || Case #%d: %I64d\n",n,k,++cont,ans);
        printf("%lld\n",ans);
    }
    return 0;
}



【WA 代码  请赐教 】

//#include <bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x) lower_bound(b+1,b+1+bn,x)-b
#define FIN      freopen("input.txt","r",stdin)
#define FOUT     freopen("output.txt","w",stdout)
#define S1(n)    scanf("%d",&n)
#define SL1(n)   scanf("%I64d",&n)
#define S2(n,m)  scanf("%d%d",&n,&m)
#define SL2(n,m)  scanf("%I64d%I64d",&n,&m)
#define Pr(n)     printf("%d\n",n)
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r

using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int MAXN=100005;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};

ll inv[maxn*2];
inline void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){ x=1; y=0; d=a; }else{ ex_gcd(b,a%b,d,y,x); y-=x*(a/b);};}
inline ll gcd(ll a,ll b){ return b?gcd(b,a%b):a;}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll ans=exgcd(b,a%b,x,y);ll temp=x;x=y;y=temp-a/b*y;return ans;}
inline ll lcm(ll a,ll b){ return b/gcd(a,b)*a;}
inline ll qpow(ll x,ll n){ll res=1;for(;n;n>>=1){if(n&1)res=(res*x)%MOD;x=(x*x)%MOD;}return res;}
inline ll inv_exgcd(ll a,ll n){ll d,x,y;ex_gcd(a,n,d,x,y);return d==1?(x+n)%n:-1;}
inline ll inv1(ll b){return b==1?1:(MOD-MOD/b)*inv1(MOD%b)%MOD;}
inline ll inv2(ll b){return qpow(b,MOD-2);}

ll a[maxn];
int main()
{
    int t;
    int n,k;
    int cont=0;
    cin>>t;
    while(t--)
    {
        mem(a,0);
        scanf("%d %d",&n,&k);
        ll sum=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            sum+=a[i];
        }
        printf("Case #%d: ",++cont);
        if(sum%k!=0)
        {
            printf("-1\n");
            continue;
        }
        ll t=sum/k;
        ll last=a[1];
        int i=1;
        ll ans=0;
        int cot=0;
        while(cot<k)
        {
            if(last>t)
            {
                int sum=last;
                while(sum>t)
                {
                    sum-=t;
                    cot++;
                    ans++;
                }
                last=sum;
            }
            else if(last<t)
            {
                int sum=last;

                if(sum+a[i+1]>t)
                {
                    last= a[++i]-(t-sum);
                    ans+=2;
                    cot++;
                }
                else
                {
                    sum+=a[++i];
                    ans++;
                    last=sum;
                }
            }
            else if(last==t)
            {
                last=a[++i];
                cot++;
            }
        }
       // printf("%d %d  || Case #%d: %I64d\n",n,k,++cont,ans);
        printf("%lld\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值