7-8月acm训练第一发(数论与计算几何)

这一部分为刘汝佳的《算法竞赛入门经典》(第一版)第三章的数论与计算几何部分,但不需要运用经典算法与模板,以模拟为主

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=48182#overview

题目分析:

A.UVA575 简单的模拟,给你一个数字,让你按照要求求出转化后得到的答案,只不过这个转化的过程和进制转化类似(真是连方法都告诉你了),不过因为没有告诉你输入数字的范围,所以用string读入会比较好(反正也是一位一位转化)

B.UVA550 未AC

C.UVA568 算给定整数的阶乘的最后一位非零数,注意不可只记录每个数的最后一位然后递推,因为如果碰到125*8这样需要进多位的数字的时候会出错,所以开JAVA大数是一个无脑的做法,或者根据输入数据的大小每次保存最后若干位也是可以的(大概5,6位的样子,不过最好开long long,不然会溢出),因为可以大致估算出一次乘法的最多的位数,另一种思路是保存每次乘法之后的2和5的个数,这样也能算出末尾0的个数,在阶乘的时候把这些2和5都去掉就可以了。

D.UVA408 给你一个递推公式和首项,问你数列中是否0,1,2,……MOD-1都存在。随意举一些数,然后打表发现如果输入的两个数互质,就是good,反之则为bad

E.UVA350 给一个递推式,求循环节的长度,由抽屉原理可得循环节长度肯定不超过M,那就开个数组跑一遍,找到循环节即可,注意一下循环节不一定从第一项开始。

F.UVA10061 一道比较坑的题,题意是让你求出n的阶乘在b进制下的后导零的个数与位数。这里位数不能用斯特林(题目故意卡了精度),那只能老老实实log累加。后导零的个数其实就等于n的阶乘最多能够整除b的几次方,方法是先对b分解质因数,然后求出b的每个素因子及其指数,这样就能求出n的阶乘能分出多少个b,再除以其指数就是答案。作者这题一开始是算b中的素因子的最大的幂,发现不对(反例大家自己去举)。

G.UVA10392 裸写分解质因数,无坑无难点。

H.UVA10250 一道所谓的计算几何,题目大意是给一个对边相等的四边形(就是平行四边形),再将其四条边向外做正方形,给出一组对边构成的2个正方形的中心,让你求另外两个正方形的中心。方法是把这给你的两个点绕中点转90度。(当然要特判两个点重合的情况)

I.UVA579 给你一个时间,求出时针与分针所夹的锐角的度数。注意分类讨论,我这里是分成了两类:在同半边与不在同半边,分别求出与0:00时刻时针的夹角,再作相加或相减的操作

J.UVA375 给一个等腰三角形的底边与高,先画一个内切圆,再画与这个三角形和内切圆均相切的圆,以此类推,求出所有圆的周长和。唯一需要注意的是这里不能用无穷等比求和公式(题目中有说最小的内切圆的半径范围,看到了吗?看到了吗?看到了吗?)

K.UVA10387 未AC

L.UVA10112 给出小于15个点的坐标,求出三个点,使得他们之间没有任何其他点且面积最大。方法:暴力枚举,因为点的个数小于等于15,所以随便怎么乱搞都行。至于判断点与三角形的位置关系,可以用如下方法:若该三角形的面积等于将另外一个点与这个三角形的顶点相连所构成的3个三角形的面积之和,那么这个点在该三角形内部。


下面贴已AC部分的代码:

A.

#include <iostream>
#include <stdio.h>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <string>
#include <string.h>
#include <sstream>
#include <cctype>
#include <climits>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <iterator>
#include <algorithm>
#include <stack>
#include <functional>
/*int类型最大值INT_MAX,short最大值为SHORT_MAX
long long最大值为LONG_LONG_MAX*/
//cout << "OK" << endl;
#define _clr(x) memset(x,0,sizeof(x))
using namespace std;
const int INF = INT_MAX;
const double eps = 1e-8;
const double EULER = 0.577215664901532860;
const double PI = 3.1415926535897932384626;
const double E = 2.71828182845904523536028;
typedef long long LL;

int main()
{
   
    //freopen("sample.in", "r", stdin);
	//freopen("sample.out", "w", stdout);
	
	string s;
	cin >> s;
	while(s!="0")
	{
   
		int res = 0,t = 1;
		for (int i = s.length()-1;i>=0;i--)
		{
   
			res+=t*(s[i]-'0');
			t = (t+1)*2-1;
		}
		cout << res << endl;
		cin >> s;
	}

    //fclose(stdin);
    //fclose(stdout); 
    return 0;
}


C.

import java.util.Scanner;
import java.math.BigInteger;
public class Main {
   
    public static void main(String[] args) {
   
        Scanner in = new Scanner(System.in);
        while(in.hasNext())
        {
   
            int x = in.nextInt();
            if(x == 0) 
            {
   
                System.out.println("1");
                continue;
            }
            BigInteger res = BigInteger.ONE;
            for (int i = 1;i<=x;i++)
                res = res.multiply(BigInteger.valueOf(i));
            String s = res.toString();
            int p = s.length()-1;
            while(s.charAt(p) == '0')
            {
   
                p--;
            }
            System.out.printf("%5d",x);
            System.out.println(" -> "+s.charAt(p));
        }
    }
    
}


D.

#include <iostream>
#include <stdio.h>
#include <fstream>
#include <iomanip>
#include <cmath>
#include <cstring>
#include <string>
#include <string.h>
#include <sstream>
#include <cctype>
#include <climits>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <iterator>
#include <algorithm>
#include <stack>
#include <functional>
/*int类型最大值INT_MAX,short最大值为SHORT_MAX
long long最大值为LONG_LONG_MAX*/
//cout << "OK" << endl;
#define _clr(x) memset(x,0,sizeof(x))
using namespace std;
const int INF = INT_MAX;
const double eps = 1e-8;
const double EULER = 0.577215664901532860;
const double PI = 3.1415926535897932384626;
const double E = 2.71828182845904523536028;
typedef long long LL;
int gcd(int a,int b)
{
   
	return b == 0?a:gcd(b,a%b
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值