省賽練習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));
        }
    }
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章