HHTC_学校集训编程题目(2)(C++,JAVA)

学校集训编程题目(2)(C++、JAVA)

Number Sequence

A number sequence is defined as follows:

f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.

Given A, B, and n, you are to calculate the value of f(n).

Input

The input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n <= 100,000,000). Three zeros signal the end of input and this test case is not to be processed.

Output

For each test case, print the value of f(n) on a single line.

Sample Input

1 1 3
1 2 10
0 0 0

Sample Output

2
5

直接暴力是会超时的,只有找规律~
超时代码:

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
using namespace std;

int f[5];

int main(){
    int A,B,n;
    while(scanf("%d %d %d",&A,&B,&n) && (A!=0 || B!=0 || n!=0)){
        f[1] = 1;
        f[2] = 1;
        for(int i=3;i<=n;i++){
            f[3] = (A*f[2] + B*f[1]) % 7;
            f[1] = f[2] % 7;
            f[2] = f[3] % 7;
            //cout<<f[1]<<" "<<f[2]<<" "<<f[3]<<endl;
        }
        printf("%d\n",f[3]);
    }
    return 0;
}

AC代码:

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
using namespace std;

int f[1005];

int main(){
    int A,B,n;
    while(scanf("%d %d %d",&A,&B,&n) != EOF && (A!=0 || B!=0 || n!=0)){
        f[1] = 1;
        f[2] = 1;
        int i;
        for(i=3;i<1000;i++){
            f[i] = (A*f[i-1] + B*f[i-2]) % 7;
            if(f[i] == 1 && f[i-1] == 1)
                break;
        }
        n = n % (i - 2);
        f[0] = f[i-2];
        printf("%d\n",f[n]);
    }
    return 0;
}

Uniform Generator

Computer simulations often require random numbers. One way to generate pseudo-random numbers is via a function of the form

seed(x+1) = [seed(x) + STEP] % MOD

where ‘%’ is the modulus operator.

Such a function will generate pseudo-random numbers (seed) between 0 and MOD-1. One problem with functions of this form is that they will always generate the same pattern over and over. In order to minimize this effect, selecting the STEP and MOD values carefully can result in a uniform distribution of all values between (and including) 0 and MOD-1.

For example, if STEP = 3 and MOD = 5, the function will generate the series of pseudo-random numbers 0, 3, 1, 4, 2 in a repeating cycle. In this example, all of the numbers between and including 0 and MOD-1 will be generated every MOD iterations of the function. Note that by the nature of the function to generate the same seed(x+1) every time seed(x) occurs means that if a function will generate all the numbers between 0 and MOD-1, it will generate pseudo-random numbers uniformly with every MOD iterations.

If STEP = 15 and MOD = 20, the function generates the series 0, 15, 10, 5 (or any other repeating series if the initial seed is other than 0). This is a poor selection of STEP and MOD because no initial seed will generate all of the numbers from 0 and MOD-1.

Your program will determine if choices of STEP and MOD will generate a uniform distribution of pseudo-random numbers.

Input

Each line of input will contain a pair of integers for STEP and MOD in that order (1 <= STEP, MOD <= 100000).

Output

For each line of input, your program should print the STEP value right- justified in columns 1 through 10, the MOD value right-justified in columns 11 through 20 and either “Good Choice” or “Bad Choice” left-justified starting in column 25. The “Good Choice” message should be printed when the selection of STEP and MOD will generate all the numbers between and including 0 and MOD-1 when MOD numbers are generated. Otherwise, your program should print the message “Bad Choice”. After each output test set, your program should print exactly one blank line.

Sample Input

3 5
15 20
63923 99999

Sample Output

     3         5    Good Choice

    15        20    Bad Choice

 63923     99999    Good Choice

这道题目做不出来可能是题目看不懂吧
题意就是找均匀分布,也就是利用这个公式,看看是不是生成的数都在0~MOD-1之间
而且每个数只出现一次就是good choice,否则就是bad
注意格式问题~

AC代码:

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
using namespace std;

int a[100005];

int main(){
    int T,n,m;
    while(cin>>n>>m){
        a[0] = 0;
        for(int i=1;i<m;i++){
            a[i] = (a[i-1] + n) % m;
        }
        sort(a,a+m);
        int f = 1;
        for(int i=0;i<m;i++){
            if(a[i] != i){
                f = 0;
                break;
            }
        }
        printf("%10d%10d",n,m);
        if(f){
            cout<<"    Good Choice"<<endl<<endl;
        }else{
            cout<<"    Bad Choice"<<endl<<endl;
        }
    }
    return 0;
}

迷瘴

通过悬崖的yifenfei,又面临着幽谷的考验——
幽谷周围瘴气弥漫,静的可怕,隐约可见地上堆满了骷髅。由于此处长年不见天日,导致空气中布满了毒素,一旦吸入体内,便会全身溃烂而死。
幸好yifenfei早有防备,提前备好了解药材料(各种浓度的万能药水)。现在只需按照配置成不同比例的浓度。
现已知yifenfei随身携带有n种浓度的万能药水,体积V都相同,浓度则分别为Pi%。并且知道,针对当时幽谷的瘴气情况,只需选择部分或者全部的万能药水,然后配置出浓度不大于 W%的药水即可解毒。
现在的问题是:如何配置此药,能得到最大体积的当前可用的解药呢?
特别说明:由于幽谷内设备的限制,只允许把一种已有的药全部混入另一种之中(即:不能出现对一种药只取它的一部分这样的操作)。
在这里插入图片描述

Input

输入数据的第一行是一个整数C,表示测试数据的组数;
每组测试数据包含2行,首先一行给出三个正整数n,V,W(1<=n,V,W<=100);
接着一行是n个整数,表示n种药水的浓度Pi%(1<=Pi<=100)。

Output

对于每组测试数据,请输出一个整数和一个浮点数;
其中整数表示解药的最大体积,浮点数表示解药的浓度(四舍五入保留2位小数);
如果不能配出满足要求的的解药,则请输出0 0.00。

Sample Input

3
1 100 10
100
2 100 24
20 30
3 100 24
20 20 30

Sample Output

0 0.00
100 0.20
300 0.23

这道题目不难,贪心吧
排个序,看看下一个浓度加进去超了没,超了就不加入
否则就加进去

AC代码:

#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
using namespace std;

int a[105];

int main(){
    int T,n,v,w;
    cin>>T;
    while(T--){
        cin>>n>>v>>w;
        int sum = 0,x = 0;
        for(int i=0;i<n;i++)
            cin>>a[i];
        sort(a,a+n);
        for(int i=0;i<n;i++){
            if(x + a[i] <= w * (i + 1)){
                x += a[i];
                sum++;
            }else{
                break;
            }
        }
        if(sum == 0){
            cout<<"0 0.00"<<endl;
        }else{
            printf("%d %.2f\n",sum*v,x*0.01/sum);
        }
    }
    return 0;
}

Buy the Ticket

The “Harry Potter and the Goblet of Fire” will be on show in the next few days. As a crazy fan of Harry Potter, you will go to the cinema and have the first sight, won’t you?

Suppose the cinema only has one ticket-office and the price for per-ticket is 50 dollars. The queue for buying the tickets is consisted of m + n persons (m persons each only has the 50-dollar bill and n persons each only has the 100-dollar bill).

Now the problem for you is to calculate the number of different ways of the queue that the buying process won’t be stopped from the first person till the last person.
Note: initially the ticket-office has no money.

The buying process will be stopped on the occasion that the ticket-office has no 50-dollar bill but the first person of the queue only has the 100-dollar bill.

Input

The input file contains several test cases. Each test case is made up of two integer numbers: m and n. It is terminated by m = n = 0. Otherwise, m, n <=100.

Output

For each test case, first print the test number (counting from 1) in one line, then output the number of different ways in another line.

Sample Input

3 0
3 1
3 3
0 0

Sample Output

Test #1:
6
Test #2:
18
Test #3:
180

思路:
大体意思就是排队买票,有50和100的两种情况,售票员没有零钱
但是又要找零钱,所以求合法排队的种数,比如说100是不能站第一个的,因为没有钱找给他
所以,第一个只能是50,还有拿有100的人数不能大于拿有50的人,否则就没有合法的队列
这里,我们就换种思路思考,合法种数=全部排列数-非法种数
合法种数很容易知道是(C(m+n,m)*m!*n!)
不理解可以画图理解一下,首先肯定是m和n全排列了,
因为是全部的,所以还要乘以从m+n中选m个放置的个数
然后不合法的种类数是(C(m+n,m + 1)*m!*n!)
这种情况肯定是不合法的,所以要减掉
所以最后的公式:((C(m+n,m)- C(m+n,m + 1))*m!*n!)
经过化简得到:((n+m)!*(m-n+1)/ (m + 1))
由于数可能会非常大,所以我选择采用JAVA来编写程序,好处理
注意n>m的特殊情况

AC代码:

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

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int k = 0;
		while(true){
			int m = in.nextInt();
			int n = in.nextInt();
			if(m == 0 && n == 0)
				break;
			if(m < n){
				System.out.println("Test #"+(++k)+":");
				System.out.println("0");
				continue;
			}
			BigInteger a = new BigInteger(m+"");
			BigInteger b = new BigInteger(n+"");
			BigInteger num = f(m+n);
			System.out.println("Test #"+(++k)+":");
			System.out.println(num.multiply(a.subtract(b).add(BigInteger.ONE)).divide(a.add(BigInteger.ONE)));
		}
	}
	public static BigInteger f(int sum){
		BigInteger num1 = BigInteger.ONE;
		BigInteger num2 = BigInteger.ONE;
		for(int i=0;i<sum;i++){
			num2 = num2.multiply(num1);
			num1 = num1.add(BigInteger.ONE);
		}
		return num2;
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值