省赛练习2——第八届福建省大学生程序设计竞赛 &补题

     这场比赛还是比较遗憾的,有两道大数题是我负责用java写的。分别是FZU 2278 YYS  和   FZU 2281Trades  ,yys主要是卡在大数类不同类型的运算问题上,以前一直没注意,临近比赛结束才调出来,好险好险;trades是贪心+java大数,思路是没问题的,用c++写可以过样例,但是数字太大就过不了,所以用java写,但怎么改都改不对,java跟c++在数组边界问题上还是规定不同的,赛后也没能A,虽然样例也过了,有点迷。。。
    
Problem 2278 YYS

Accept: 160    Submit: 431
Time Limit: 1000 mSec    Memory Limit : 262144 KB

Problem Description

Yinyangshi is a famous RPG game on mobile phones.

Kim enjoys collecting cards in this game. Suppose there are n kinds of cards. If you want to get a new card, you need to pay W coins to draw a card. Each time you can only draw one card, all the cards appear randomly with same probability 1/n. Kim can get 1 coin each day. Suppose Kim has 0 coin and no cards on day 0. Every W days, Kim can draw a card with W coins. In this problem ,we define W=(n-1)!.

Now Kim wants to know the expected days he can collect all the n kinds of cards.

Input

The first line an integer T(1 ≤ T ≤ 10). There are T test cases.

The next T lines, each line an integer n. (1≤n≤3000)

Output

For each n, output the expected days to collect all the n kinds of cards, rounded to one decimal place.

Sample Input

4
1
2
5
9

Sample Output

1.0
3.0
274.0
1026576.0 
   

              我们假设已经有了a张卡片的话,如果我们想要得到第a+1张,我们抽中它的概率显然就是(n-a)/n,概率的倒数就是它的期望,所以他的期望就是n/(n-a),累加的话总的期望就是n(1+1/2+1/3+...+1/n),然后乘以(n-1)!,最终公式为n!(1+1/2+1/3+...+1/n).尽量避免两个不同类型的大数类运算。

              

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;

public class YYS {
	static  BigInteger jie(int x)
	{
		BigInteger sum= BigInteger.ONE;
	    for(int i=1;i<=x;i++)
	    {
	    	BigInteger z= BigInteger.valueOf(i);
	        sum=sum.multiply(z);
	    }
	    return sum;
	}
	/*static BigDecimal qi(int x)
	{
		BigDecimal sum =BigDecimal.valueOf(0);
	    for(double i=1;i<=x;i++)
	    {
	    	double z=1/i;
	        sum=sum.add(BigDecimal.valueOf(z));
	    }
	    return sum.multiply(BigDecimal.valueOf(x));
	}
*/
	public static void main(String[] args) {
	    int t=0;;
	    Scanner cin=new Scanner(System.in);
	    t=cin.nextInt();
	    for(int k=0;k<t;k++)
	    {
	    	
	        int n;
	        n=cin.nextInt();
	        BigInteger ans=BigInteger.ZERO;
	        BigInteger sum1=jie(n);
        
            for(int i=1;i<=n;i++){
                ans=ans.add(sum1.divide(BigInteger.valueOf(i)));
            }
            System.out.println(ans+".0");
	       /* BigDecimal sum1=jie(n-1);
	        BigDecimal sum2=qi(n);
	        BigDecimal aaa=sum1.multiply(sum2);
	        System.out.println(String.format("%.1f", aaa));*/
	    }


	}

}


Problem 2281 Trades

Accept: 119    Submit: 635
Time Limit: 1000 mSec    Memory Limit : 262144 KB

Problem Description

This is a very easy problem.

ACMeow loves GTX1920. Now he has m RMB, but no GTX1920s. In the next n days, the unit price of GTX1920 in the ith day is Ci RMB. In other words, in the ith day, he can buy one GTX1920 with Ci RMB, or sell one GTX1920 to gain Ci RMB. He can buy or sell as many times as he wants in one day, but make sure that he has enough money for buying or enough GTX1920 for selling.

Now he wants to know, how many RMB can he get after the n days. Could you please help him?

It’s really easy, yeah?

Input

First line contains an integer T(1 ≤ T ≤20), represents there are T test cases.

For each test case: first line contains two integers n(1 ≤ n ≤2000) and m(0 ≤ m ≤1000000000). Following n integers in one line, the ith integer represents Ci(1 ≤ Ci ≤1000000000).

Output

For each test case, output "Case #X: Y" in a line (without quotes), where X is the case number starting from 1, and Y is the maximum number of RMB he can get mod 1000000007.

Sample Input

23 11 2 34 11 2 1 2

Sample Output

Case #1: 3Case #2: 4 


题意:

买卖GTX1920,已知未来一段时间每块GTX1920的价格,问买卖后最大的收益

  • 每次买入都尽可能多买,每次卖都全卖
  • 在每个局部价格山谷都买入,然后在接下来的第一个局部价格山顶卖出
  • 最后的资金会很大,超过long long的范围,但是中间结果不能取模,不然无法计算出下次购买GTX1920的数量,所以使用BigInteger来计算
  
import java.util.Scanner;
import java.math.BigInteger;

public class Main {
    public static void main(String[] args) {
        Scanner cin=new Scanner(System.in);
        int T;
        int n,m;
        int[] c = new int[2005];
        T=cin.nextInt();
        BigInteger ans,mod=BigInteger.valueOf(1000000007);
        for(int xx=1;xx<=T;++xx){
            n=cin.nextInt();
            m=cin.nextInt();
            ans=BigInteger.valueOf(m);
            for(int j=0;j<n;++j) {
                c[j]=cin.nextInt();
            }
            int i,j,k;
            for(i=0;i<n;) {
                j=i;
                while(j<n-1&&c[j+1]<=c[j])++j;
                if(j==n-1)break;
                k=j;
                while(k<n-1&&c[k+1]>c[k])++k;
                BigInteger res=ans.mod(BigInteger.valueOf(c[j]));
                BigInteger buy=ans.divide(BigInteger.valueOf(c[j]));
                buy=buy.multiply(BigInteger.valueOf(c[k]));
                ans=res.add(buy);
                i=k+1;
            }
            System.out.println("Case #"+xx+": "+ans.mod(mod));
        }
    }
}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值