2012 winter training @HIT Day 3 解题报告

冬训第三天。我发现参加寒假集训contest的同学是一天比一天少。

今天练习java,四道题其实只有Problem B值得一说,而且我还是在『亮亮』学长的思路指点下才写出来的代码。效果倒是真的很不错。

 http://acm.hit.edu.cn/hoj/contest/view?id=100129

 

Problem A:Hello Java

给出A、B、P求 A * B % P,唯一一点就是三者全都0< <=2^63-1。目测C++的longlong会溢出,经我的实地检验果然溢出

(╮(╯_╰)╭|||使用“分配律”((A % P) * (B % P)) % P 也是不行哒)。用java的biginteger一击制敌。

/*This Code is Submitted by acehypocrisy for Problem 4000090 at 2012-01-20 09:21:44*/
import java.util.*;
import java.math.*;

public class Main {
public static void main(String args[]){
        Scanner cin = new Scanner(System.in);
        while (cin.hasNextBigInteger()){
                BigInteger A = cin.nextBigInteger();
                BigInteger B = cin.nextBigInteger();
                BigInteger P = cin.nextBigInteger();
                System.out.println(A.multiply(B).mod(P));
        }
}
}

 

Problem B:Ugly Numbers

寻找丑数,这道题比原题简单,只要输出第1500个即可,所以可以选择本地跑出结果后print上去。在1s之内出结果也是没问题的。下面的代码的思路是亮神指点的,我等蒟蒻受益匪浅……

首先要明确一点的是,因为丑数的因数只有2 3 5三个数,所以说所有丑数(除1外)都是是可以根据之前的丑数推出来的。

存三个数组索引,把他想成三组一样的数据也不为过。一组数据只负责*2,一组只负责*3,一组只负责*5。这样从1开始就可以推出所有的丑数了。首先要保证当前这三个索引所存的数据分别*2、*3、*5之后比目前最大的丑数还要大。然后比较他们*2、*3、*5之后的数据,选择小的那个作为新的丑数,并且对索引进行一些处理以满足上面说的那一条“保证”。然后就是循环了,循环到1500即可。

本地测试0.016s给出结果,oj评测0.00s。

#include <stdio.h>
#include <algorithm>
using namespace std;

struct Index{
    int temp;
    int index;
    int step;
}myindex[3];

bool compare(const Index& A, const Index& B){
    if (A.temp < B.temp)
        return true;
    else
        return false;
}

int ugly_number[1500];

int main()
{
    myindex[0].index = myindex[1].index = myindex[2].index = 0;
    myindex[0].step = 2;
    myindex[1].step = 3;
    myindex[2].step = 5;
    int n = 1;
    ugly_number[0] = 1;
    while (n < 1500){
        myindex[0].temp = ugly_number[myindex[0].index] * myindex[0].step;
        myindex[1].temp = ugly_number[myindex[1].index] * myindex[1].step;
        myindex[2].temp = ugly_number[myindex[2].index] * myindex[2].step;
        sort(&myindex[0], &myindex[3], compare);
        for(int i = 0; i < 3; i++){
            if (myindex[i].temp > ugly_number[n-1]){
                myindex[i].index++;
                ugly_number[n] = myindex[i].temp;
                n++;
                break;
            }
        }
        for(int i = 0; i < 3; i++){
            while (ugly_number[myindex[i].index] * myindex[i].step <= ugly_number[n-1])
                myindex[i].index++;
        }
    }
    printf("The 1500'th ugly number is %d.\n", ugly_number[1499]);
    return 0;
}

另外要提到的是我原来的代码myindex是叫index的,但是交上去编译错误,大意就是和string.h里面的一个函数重名了。。。

哦,在多说一句,代码里面中间的for当时是为了挑出最小的、而且比目前最大丑数大的那个数,不过既然有了下面的while,这句for就显得有点多余了。。

 

Problem C & D:Fibonacci Sequence

最最基本的斐波那契数列了,其实C和D是一样的,只不过D要求高精度了而已。。所以只贴D的代码了,用java

/*This Code is Submitted by acehypocrisy for Problem 4000094 at 2012-01-20 09:35:58*/
import java.util.*;
import java.math.*;

public class Main {
public static void main(String args[]){
        Scanner cin = new Scanner(System.in);
        while (cin.hasNextInt()){
                int n = cin.nextInt();
                BigInteger F1 = BigInteger.valueOf(0);
                BigInteger F2 = BigInteger.valueOf(1);
                BigInteger F3 = F1.add(F2);
                for (int i = 0;i < n - 2; i++){
                        F1 = F2;
                        F2 = F3;
                        F3 = F1.add(F2);
                }
                if (n == 0)
                        System.out.println(0);
                else if (n == 1)
                        System.out.println(1);
                else
                        System.out.println(F3);
        }
}
}
 
posted @ 2012-01-20 22:41  dontpanic  阅读(234)  评论(0编辑  收藏  举报