数论题集合

1. 给出一个数n,求1到n中,有多少个数不是2 5 11 13的倍数。

//给出一个数n,求1到n中,有多少个数不是2 5 11 13的倍数。
#define int long long 
int get(int n) {                       //容斥原理
    int cnt = n;
    cnt -= n / 2;
    cnt -= n / 5;
    cnt -= n / 11;
    cnt -= n / 13;
    cnt += n / 10;
    cnt += n / 22;
    cnt += n / 26;
    cnt += n / 55;
    cnt += n / 65;
    cnt += n / (11 * 13);
    cnt -= (n / 110);
    cnt -= (n / 130);
    cnt -= n / (2 * 11 * 13);
    cnt -= n / (5 * 11 * 13);
    cnt += n / (2 * 5 * 11 * 13);
    return cnt;
}
signed main()
{
    int n;
    ios::sync_with_stdio, cin.tie(0), cout.tie(0);
    while(cin >> n)
    cout << get(n)<<endl;
    return 0;
}

2.最小公倍数

typedef unsigned long long ULL;
int main(){
  ULL a,b;
    cin>>a>>b;
    ULL c=lcm(a,b);    //lcm 函数:a*b/__gcd(a,b)
    cout<<c<<endl;
    return 0;
}

3.

新浪微博上有一个帖子给出了一道题:全班有 50 人,有 30 人会游泳,有 35 人会篮球,有 42 人会唱歌,有 46 人会骑车,至少有( )人四项都会。
发帖人不会做这道题,但是回帖有会做的:每一个才艺是一个技能点,一共是 30 + 35 + 42 + 46 = 153 个技能点,50 个人假设平均分配,每人都会 3 个技能那也只有 150,所以至少有 3 人会四个技能。
本题就请你写个程序来自动解决这类问题:给定全班总人数为 n,其中有 m 项技能,分别有 k1​、k2​、……、km​ 个人会,问至少有多少人 m 项都会。

输入格式:

输入在第一行中给出 2 个正整数:n(4≤n≤1000)和 m(1<m≤n/2),分别对应全班人数和技能总数。随后一行给出 m 个不超过 n 的正整数,其中第 i 个整数对应会第 i 项技能的人数。

输出格式:

输出至少有多少人 m 项都会。

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n, m, sum=0;
    cin >> n >> m;
    vector<int> a(m,0);
    for(int i=0; i<m; i++) {
        cin >> a[i];
        sum += a[i];
    }
    int tmp = sum - n*(m-1);
    cout << max(0,tmp);
    return 0;
}

4.

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int n, sum;
	while(cin >> n)
	{
		if(n % 2 == 0){
			sum = (n*(n+2)*(2*n+1)) / 8;
			cout << sum;
		}else{
			sum = ((n+1)*(2*n*n+3*n-1)) / 8;
			cout << sum;
		}
		cout << endl;
	}
	return 0;
}

5.

Description

小学题目,给定除数和被除数,求余数

Input

多组测试数据,每组测试数据包含两个整数n,k(1<=n<=10^2000,1<=k<=1000)

Output

对于每组测试数据,输出n%k

#include<bits/stdc++.h>
using namespace std;
char a[2005];
int main(void)
{
	int k;
	while(~scanf("%s %d",a,&k))
	{
		int sum=0;
		int len=strlen(a);
		for(int i=0;i<len;i++)
		{
			sum=(sum*10+a[i]-'0')%k;
		}
		printf("%d\n",sum);
	}
	return 0;
}

6.现有n个ACMer,杰哥需要选择m个进入集训队,请告诉杰哥他有多少种不同的选择。

#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
	int n, m;
	while(1)
	{
		cin >> n >> m;
		if(n==0&&m==0) break;
		if(m > n/2) m = n-m;
		int sum = 1;
		if(m == 0) cout << 1 << endl;
		else{
			for(int i=1; i<=m; i++)
			{
				sum = sum*(n-m+i) / i;
			}
			cout << sum << endl;
		}
	}
	return 0;
}

7.

Description

田忌和齐王赛马,两人各出n匹马,赢一场比赛得200两银子,输了赔200银子,平局不赔不赚.已知两人每匹马的速度,问田忌最多能赢多少银子.

Input

多组测试数据,

每组数据的第一行是一个整数n。 (1<=n<=1000)

第二行包括n个整数既田忌每匹马的速度.

第三行包括n个整数既齐王每匹马的速度.

每匹马的速度不超过1000.

Output

对于每组数据输出一行有一个整数代表田忌最多能赢多少银子

Sample Input

3 92 83 71 95 87 74 2 20 20 20 20 2 20 19 22 18

Sample Output

200 0 0
#include <bits/stdc++.h>
using namespace std;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, i, j;
	cin >> n;
	long long a, b;
	for(int i=1; i<=n; i++)
	{
		cin >> a;
		b = sqrt(a);
		for(j=2; j*j <= b; j++)
		{
			if(b%j == 0) break;
		}
		if(j*j > b && b*b == a && a > 1)
		{
			cout << "YES\n";
		}else cout << "NO\n";
	}
	return 0;
}

8.

矩形中有多少个矩形

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int _;
	cin >> _;
	while(_--)
	{
		int n, m;
		cin >> n >> m;
		int sum1 = 0, sum2 = 0;
		for(int i=n; i>0; i--) sum1 += i;
		for(int i=m; i>0; i--) sum2 += i;
		cout << sum1 * sum2 << endl;
	}
	return 0;
}

9.p1226快速幂

#include <bits/stdc++.h>
#define int long long
using namespace std;
int b, p, k;
int qpow(int base, int p){
	if(p == 1) return base;
	else{
		if(p == 0)
		{
			return 1;
		}else{
			int ans = qpow(base,p/2)%k;
			int ans1 = (ans%k * ans%k) % k;
			if(p%2 == 1){
				ans1 = (ans1%k * base%k) % k;
			}
			ans1 = ans1%k;
			return ans1;
		}
	}
}
signed main()
{
	cin >> b >> p >> k;
	int ans = qpow(b,p);
	ans = ans % k;
	cout << b <<"^"<<p<<" mod "<<k<<"="<<ans;
	return 0;
}

10.p1348

#include<iostream>
using namespace std;
int main()
{
    int n1,n2,i,ans=0;
    cin>>n1>>n2;
    for(i=n1;i<=n2;i++)
    if(i%4==0||i%2!=0)ans++;  //奇数或4的倍数
    cout<<ans<<endl;
    return 0;
}
/*
step 1:a^2-b^2=(a+b)(a-b)=>a+b与a-b奇偶性相同

step 3:所以(a+b)(a-b)要么是奇数,要么是4的倍数

step 4:couple number要么是奇数,要么是4的倍数

step 5:验证:若n=2k-1,则(a+b)(a-b)=2k-1

a+b=2k-1, a-b=1, a=k, b=k-1正确!

若n=4k,则(a+b)(a-b)=4k, a+b=2k, a-b=2, a=k+1, b=k-1正确!
*/

11.洛谷p1579哥德巴赫猜想(升级

/*
这个题目求任意一个大于九的奇数等于三个质数的和,题目说明了第一个质数要最小,其次第二个,据此可以进行优化循环的次数。然后就是进入正题了 ,首先先要明白一件事,三个数相加为奇数,只有两种可能
①两个偶数加一个奇数.
②三个奇数.
①先判断前两个质数都是偶数的情况,因为偶数中只有2是素数,那么就只要判断这个(n-4)是否为素数,如果是,就直接输出2,2,n-4。
②如果这三个数都是质数,那么从i=3开始循环,并保证i为奇数并且i为素数,再在第二重循环里面让j=i并保证j为奇数且j为素数,最后只要判断(n-i-j)是否为奇数且为素数就行了,满足就输出答案。
*/
#include<bits/stdc++.h>
using namespace std;
int check(int x){
	for (int i=2;i*i<=x;i++)
	if(x%i==0) return 0;
	return 1;
}
int main(){
	int n;
	cin>>n;
	if(check(n-4)) {
	cout<<"2 "<<"2 "<<n-4;
    return 0;
    }     //第一种情况 
	for (int i=3;i<n;i++)//第二种情况
	if((i%2)!=0&&check(i))//优化
	for (int j=i;j<n;j++)
		if((j%2)!=0&&check(j))//优化
		if(check(n-i-j)) {
		cout<<i<<" "<<j<<" "<<n-i-j;return 0;//不用循环第三个数,优化。
        }
}

12.洛谷p1134

#include<bits/stdc++.h>
using namespace std;
int n, ans=1;
int a[4] = {6,8,4,2};
int main() {
	scanf("%d", &n);
	while(n > 0) {
		for (int i=1; i<=n%10; i++)
		{
			if(i!=5) ans = ans*i%10;
		}
		n = n/5;
		ans = ans * a[n%4] % 10;
	}
	cout << ans;
	return 0;
}

 13.洛谷p1112

#include<bits/stdc++.h>
using namespace std;
int m[10000005];
int a, b, c, d, e;
int main()
{
	cin >> a >> b >> c >> d >> e;
	for (int i=a; i<=b; i++)
	{
		for (int j=0; j<i; j++)
		{
			for(int k=1; k<i; k++)
			{
				if(j != k)
				{
					int v1 = 0;
					int v2 = 0;
					while(v1 <= d)
					{
						if(v2 % 2 == 0)
						{
							v1 = v1*i + j;
						}else{
							v1 = v1*i + k;
						}
						v2++;
						if(v1 >= c && v1 <= d)
						{
							m[v1] ++;
						}
					}
				}
			}
		}
	}
	for (int i=c; i<=d; i++)
	{
		if(m[i] == e)
		{
			cout << i << endl;
		}
	}
	return 0;
}

14.洛谷p1327

#include<bits/stdc++.h>
#define L1 long long
using namespace std;
const int N = 1e5+5;
map<int,int> F;
int a[N], b[N];
int n, m, ans;
int main()
{
	scanf("%d", &n);
	for (int i=1; i<=n; i++) {
	   scanf("%d",&a[i]);
	   b[i] = a[i];
	   F[a[i]] = i;
    }
    sort(b+1, b+n+1);
    for (int i=1; i<=n; i++)
    {
    	if(a[i] != b[i]) {
    		ans ++;
    		int x = F[b[i]];
    		F[a[i]] = x;
    		a[x] = a[i];
		}
	}
	printf("%d", ans);
	return 0;
}

15.买不到的数目

Description

小明开了一家糖果店。他别出心裁:把水果糖包成4颗一包和7颗一包的两种。糖果不能拆包卖。 小朋友来买糖的时候,他就用这两种包装来组合。当然有些糖果数目是无法组合出来的,比如要买 10 颗糖。 你可以用计算机测试一下,在这种包装情况下,最大不能买到的数量是17。大于17的任何数字都可以用4和7组合出来。

本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。

Input

 两个正整数,表示每种包装中糖的颗数(都不多于1000)

Output

  一个正整数,表示最大不能买到的糖数

Sample Input

4 7

Sample Output

17

#include<bits/stdc++.h>
using namespace std;
void solve()
{
	int x, y;
	cin >> x >> y;
	cout << x*y - x - y;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t = 1;
	//cin >> t;
	while(t--)
	{
		solve();
	}
	return 0;
}
/*
代码假设输入的 x 和 y 互质。根据数论中的 “邮票问题”(或 “青蛙问题”),若两个正整数 a 和 b 互质,最大不能组合出的数为 a * b - a - b.例如,题目中 4 和 7 互质,4 * 7 - 4 - 7 = 17,与题目示例一致。
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值