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

本文基于刘汝佳的《算法竞赛入门经典》第一版,重点介绍了数论和计算几何的AC题目,包括UVA的多个问题,如简单的模拟、阶乘末位非零数计算、递推序列分析等。通过实例分析和代码展示,讲解了解题思路和方法,如模拟、大数处理、分解质因数等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

题目链接: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);
}
int main()
{
    //freopen("sample.in", "r", stdin);
	//freopen("sample.out", "w", stdout);
	
	int a,b,t = 0;
	while(scanf("%d%d",&a,&b) == 2)
	{
		char res[20];
		if(gcd(a,b) == 1) strcpy(res,"Good Choice");
		else strcpy(res,"Bad Choice");
		//if(t != 0) printf("\n");
		//else t++;
		printf("%10d%10d    %s\n\n",a,b,res);
	}

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


E.

#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);
	
	int a,b,c,d,i1 = 0;
	cin >> a >> c >> d >> b;
	while(a || b || c || d)
	{
		
		int res,x[10010] = {0},y[10010] = {0},i = 0;
		x[i] = b;
		while(!y[b])
		{
			y[b] = i++;
			b = (a*b+c)%d;
			x[i] = b;
		}
		res = i-y[b];
		//cout << i << " " << y[b] << endl;
		
		cout << "Case " << ++i1 << ": ";
		cout << res << endl;
		cin >> a >> c >> d >> b;
	}

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


F.

#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 f[805] = {0},g[805] = {0};
int maxfac(int b)
{
	int res = 1,x[805] = {0},ma = 0,b2 = b;
	for (int i = 2;i<=b;i++)
	{
		int temp = 1;
		while(b%i == 0)
		{
			b/=i;
			temp=i;
			x[i]++;
		}
		if(temp>res)
		{
			res = temp;
			ma = i;
		}
	}

	f[b2] = res;
	return x[ma];
}

int main()
{
    //freopen("sample.in", "r", stdin);
	//freopen("sample.out", "w", stdout);
	
	for(int i = 2;i<=800;i++)
	g[i] = maxfac(i);
	//cout << f[2] << " " << g[2] << endl;
	//for(int i = 2;i<=800;i++)
	//cout << i << " " << f[i] << endl;
	unsigned long long a,b,x;
	while(cin >> a >> b)
	{
		int res1 = 0,p = f[b],q = g[b];
		//cout << p << endl;
		x = a;
		while(x)
		{
			res1+=x/p;
			x/=p;
		}
		res1/=q;
		int res2 = 0;
		double x = 0;
		for(int i = 1;i<=a;i++) x+=log(i);
		x/=log((double)b);
		x+=eps;
		res2 = x+1;
		
		cout << res1 << " " << res2 << endl;
	}
	
    //fclose(stdin);
    //fclose(stdout); 
    return 0;
}


G.

#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);
	
	LL n;
	cin >> n;
	while(n>0)
	{
		for(LL i = 2;i*i<=n;i++)
		while(n%i == 0)
		{
			cout << "    " << i << endl;
			n/=i;
		}
		if(n!=1) cout << "    " << n << endl;
		cout << endl;
		cin >> n;
	}

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


H.

#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);
	
	double x1,x2,y1,y2,midx,midy,ax1,ax2,ay1,ay2;
	while(cin >> x1 >> y1 >> x2 >> y2)
	{
		if(abs(x1-x2)<eps && abs(y1-y2)<eps)
		{
			cout << "Impossible." << endl;
			continue;
		}
		midx = 0.5*(x1+x2);
		midy = 0.5*(y1+y2);
		double dx = midx-x1,dy = midy-y1;
		ax1 = midx-dy;
		ay1 = midy+dx;
		ax2 = midx+dy;
		ay2 = midy-dx;
		cout << fixed << setprecision(10) << ax1 << " " << ay1 << " " << ax2 << " " << ay2 << endl;
	}

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


I.

#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);
	
	int h,m;
	char ch;
	cin >> h >> ch >> m;
	while(h)
	{
		int p1,p2;
		if(h<6||h == 12)p1 = 1;else p1 = 2;
		if(m<30)p2 = 1;else p2 = 2;
		double deg1,deg2;
		deg2 = m*6.0;
		deg1 = h*30.0;
		deg1+=m*0.5;
		if(deg1>=360) deg1-=360.0;
		if(deg1>180)deg1=360-deg1;
		if(deg2>180)deg2 = 360-deg2;
		//cout << deg1 << " " << deg2 << endl;
		double res2 = (deg1+deg2<180)?(deg1+deg2):(360.0-deg1-deg2);
		if(p1 == p2) cout << fixed << setprecision(3) << abs(deg1-deg2) << endl;
		else cout << fixed << setprecision(3) << res2 << endl;
		
		cin >> h >> ch >> m;
	}

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


J.

#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);
	
	int t;
	cin >> t;                        
	while(t--)
	{
		double c,h,r1,c2,h2,r2,res = 0,q;
		cin >> c >> h;
		r1 = c*h/(c+sqrt(c*c+4*h*h));
		h2 = h-2*r1;
		c2 = c*h2/h;
		r2 = c2*h2/(c2+sqrt(c2*c2+4*h2*h2));
		q = r2/r1;
		res+=r1*2*PI;
		r1*=q;
		while(r1>=1e-6)
		{
			res+=r1*2*PI;
			r1*=q;
		}
		
		cout << fixed << setw(13) << res <<endl;
		
		if(t!=0)
		cout << endl;
	}

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


L.

#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;
struct Mypoint
{
	char ch;
	int x;
	int y;
}poi[500];
double f(int a,int b,int c)
{
	return 0.5*fabs((poi[c].y-poi[a].y)*(poi[b].x-poi[a].x)-(poi[c].x-poi[a].x)*(poi[b].y-poi[a].y));
}
int main()
{
    //freopen("sample.in", "r", stdin);
	//freopen("sample.out", "w", stdout);
	
	int n;
	cin >> n;
	while(n)
	{
		string ma = "AAA";
		for(int i = 0;i<n;i++)
		cin >> poi[i].ch >> poi[i].x >> poi[i].y;
		for(int i = 0;i<n-2;i++)
		for(int j = i+1;j<n-1;j++)
		for(int k = j+1;k<n;k++)
		{
			double s_temp = f(i,j,k);
			int i1 = ma[0]-'A',i2 = ma[1]-'A',i3 = ma[2]-'A',p = 0;
			double s = f(i1,i2,i3);
			if(s_temp<=s) continue;
			for(int l = 0;l<n;l++)
			{
				if(l == i||l == j|| l == k) continue;
				if(s_temp == f(i,l,k)+f(i,j,l)+f(j,k,l))
				{
					p = 1;
					break;
				}
			}
			if(p) continue;
			ma[0] = 'A'+i;
			ma[1] = 'A'+j;
			ma[2] = 'A'+k;
		}
		cout << ma << endl;
		
		cin >> n;
	}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值