2014 Multi-University Training Contest 7 1003 1005

http://acm.hdu.edu.cn/showproblem.php?pid=4937

Lucky Number

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1123    Accepted Submission(s): 333


Problem Description
“Ladies and Gentlemen, It’s show time! ”

“A thief is a creative artist who takes his prey in style... But a detective is nothing more than a critic, who follows our footsteps...”

Love_Kid is crazy about Kaito Kid , he think 3(because 3 is the sum of 1 and 2), 4, 5, 6 are his lucky numbers and all others are not. 

Now he finds out a way that he can represent a number through decimal representation in another numeral system to get a number only contain 3, 4, 5, 6. 

For example, given a number 19, you can represent it as 34 with base 5, so we can call 5 is a lucky base for number 19. 

Now he will give you a long number n(1<=n<=1e12), please help him to find out how many lucky bases for that number. 

If there are infinite such base, just print out -1.
 

Input
There are multiply test cases.

The first line contains an integer T(T<=200), indicates the number of cases. 

For every test case, there is a number n indicates the number.
 

Output
For each test case, output “Case #k: ”first, k is the case number, from 1 to T , then, output a line with one integer, the answer to the query.
 

Sample Input
  
  
2 10 19
 

Sample Output
  
  
Case #1: 0 Case #2: 1
Hint
10 shown in hexadecimal number system is another letter different from ‘0’-‘9’, we can represent it as ‘A’, and you can extend to other cases.
 

Author
UESTC
 

Source
 

给一个数N,求N能否转化成一个n进制数X,且X只由3,4,5,6组成。求X的个数。详见代码注释。


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;

typedef long long ll;
ll MIN;//MIN代表最小进制数,比如如果N能表示成两位的X进制数,那么当N表示成三位的X’进制时,X’<X;所以记录下最小的X,为之后进制数高时减少复杂度


//n能表示成两位数时
bool cal2(ll n,int i,int j){
    ll k=n-j;
    ll base=k/i;
    if(k%i!=0) return false;
    else {
        if(base>i&&base>j) {MIN=min(MIN,base);return true;}
    }
    return false;
}

//n能表示成三位数时
bool cal3(ll n,int i,int j,int k){
    ll kk=k-n;
    ll deta=j*j-4*i*kk;
    if(deta<0) return false;
    ll dd=sqrt(deta);
    if(dd*dd!=deta) return false;
    ll xx=(-j-dd)/(2*i);
    if((-j-dd)%(2*i)==0&&xx>i&&xx>j&&xx>k){
        MIN=min(xx,MIN);
        return true;
    }
    xx=(-j+dd)/(2*i);
    if((-j+dd)%(2*i)==0&&xx>i&&xx>j&&xx>k){
        MIN=min(xx,MIN);
        return true;
    }
    return false;
}


bool cal4(ll n,ll i){
    ll k=n%i;
    while(n){
        if(k!=3&&k!=4&&k!=5&&k!=6) return false;
        n/=i;
        k=n%i;
    }
    return true;
}

int main()
{
    //freopen("1003.in","r",stdin);
    //freopen("10032.out","w",stdout);
    int t;
    scanf("%d",&t);
    for(int ii=1;ii<=t;++ii){
        ll n;
        scanf("%I64d",&n);
        MIN=n;
        printf("Case #%d: ",ii);
        if(n==3||n==4||n==5||n==6){
            printf("-1\n");
            continue;
        }

        int ans=0;

        for(int i=3;i<=6;i++)
            for(int j=3;j<=6;j++)
                if(cal2(n,i,j)) ans++;

        for(int i=3;i<=6;i++)
            for(int j=3;j<=6;j++)
                for(int k=3;k<=6;k++)
                    if(cal3(n,i,j,k)) ans++;

        //如果两位和3位都没有,那最大的进制就是6*base^(X-1)=10^12,因为之前X=3时不满足,所以此时X最小=4,故max{base}=10^4
        for(ll i=4;i<min(MIN,7000ll);i++)
            if(cal4(n,i)) ans++;


        printf("%d\n",ans);
    }
    return 0;
}


http://acm.hdu.edu.cn/showproblem.php?pid=4939


Stupid Tower Defense

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1315    Accepted Submission(s): 386


Problem Description
FSF is addicted to a stupid tower defense game. The goal of tower defense games is to try to stop enemies from crossing a map by building traps to slow them down and towers which shoot at them as they pass.

The map is a line, which has n unit length. We can build only one tower on each unit length. The enemy takes t seconds on each unit length. And there are 3 kinds of tower in this game: The red tower, the green tower and the blue tower. 

The red tower damage on the enemy x points per second when he passes through the tower.

The green tower damage on the enemy y points per second after he passes through the tower.

The blue tower let the enemy go slower than before (that is, the enemy takes more z second to pass an unit length, also, after he passes through the tower.)

Of course, if you are already pass through m green towers, you should have got m*y damage per second. The same, if you are already pass through k blue towers, the enemy should have took t + k*z seconds every unit length.

FSF now wants to know the maximum damage the enemy can get.
 

Input
There are multiply test cases.

The first line contains an integer T (T<=100), indicates the number of cases. 

Each test only contain 5 integers n, x, y, z, t (2<=n<=1500,0<=x, y, z<=60000,1<=t<=3)
 

Output
For each case, you should output "Case #C: " first, where C indicates the case number and counts from 1. Then output the answer. For each test only one line which have one integer, the answer to this question.
 

Sample Input
  
  
1 2 4 3 2 1
 

Sample Output
  
  
Case #1: 12
Hint
For the first sample, the first tower is blue tower, and the second is red tower. So, the total damage is 4*(1+2)=12 damage points.
 

Author
UESTC
 

Source
 

dp,当时没有想清楚,要有红色一定放最后是没问题的,接下来就是方程,dp[j][k]表示前j个长度内有k个蓝塔造成的伤害的最大值。前面wa了几次,居然忘记乘法给溢出了,最近特别不细心,静心啊。

dp[j][k]=max(dp[j-1][k]+(ll)(j-k-1)*(t+k*z)*y,dp[j-1][k-1]+(ll)(j-k)*(t+(k-1)*z)*y);



#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define MAXN 1550

using namespace std;

typedef long long ll;

ll dp[MAXN][MAXN];

int main()
{
    int T;
    scanf("%d",&T);
    memset(dp,0,sizeof(dp));
    for(int i = 1; i <= T; ++i) {
        int n, x, y, z, t;
        scanf("%d%d%d%d%d",&n, &x, &y, &z, &t);
        printf("Case #%d: ",i);
        ll ans=(ll)n*x*t;
        ll damage=0;

        for(int j=1;j<=n;j++){
            dp[j][0]=dp[j-1][0]+y*(j-1)*t;
            ans=max(dp[j][0]+(ll)(n-j)*t*x+(ll)(n-j)*t*y*j,ans);
        }

        for(int j = 1; j <= n; j++)
            for(int k = 1; k <= j; k++){
                if(k==j)dp[j][k]=0;
                else dp[j][k]=max(dp[j-1][k]+(ll)(j-k-1)*(t+k*z)*y,dp[j-1][k-1]+(ll)(j-k)*(t+(k-1)*z)*y);
                damage=dp[j][k]+(ll)(n-j)*(t+k*z)*x+(ll)(n-j)*(t+k*z)*y*(j-k);
                ans=max(ans,damage);
            }
        printf("%I64d\n",ans);
        memset(dp,0,sizeof(dp));
    }
    return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值