冬令营:数学专题

A - A^B Mod C

给出3个正整数A B C,求A^B Mod C。

例如,3 5 8,3^5 Mod 8 = 3。

Input

3个正整数A B C,中间用空格分隔。(1 <= A,B,C <= 10^9)

Output

输出计算结果

Sample Input

3 5 8

Sample Output

3
#include<stdio.h>
#include<math.h>

int main ()
{ 
unsigned long long int A, C;	
	unsigned long long int ans=1,B;
	scanf("%llu %llu %llu",&A,&B,&C);
	A=A%C;
	while(B>0){
		if(B%2==1)
			ans=(ans*A)%C;
		B=B/2;
		A=(A*A)%C;
		
	}
	printf("%llu", ans);
}

C - 判决素数个数

输入两个整数X和Y,输出两者->>之间<<-的素数个数(包括X和Y)。

Input

两个整数X和Y(1 <= X,Y <= 105)。

Output

输出一个整数,表示X,Y之间的素数个数(包括X和Y)。

Sample Input

1 100

Sample Output

25
#include<stdio.h>
#include<math.h>

int prime(int p) {
	if (p <= 1)
		return 0;
	for (int i = 2; i <= (sqrt(p)); i++)
		
	{
		if (p % i == 0) {
			return 0;
		}
	}
	return 1;
}

int main()

{
	int count = 0;
	int X, Y;
	scanf("%d %d", &X, &Y);
	if (X < Y) {
		for (int i = X; i <= Y; i++) {
		if(	prime(i))
			count++;
			
		}
	} else {
		for (int i = Y; i<= X; i++) {
			if(prime(i))
			count++;
			
		}
	}
	printf("%d", count);
	return 0;
}

D - 矩阵乘法

计算两个矩阵的乘法。n \times mn×m 阶的矩阵 AA 乘以 m \times km×k 阶的矩阵 BB 得到的矩阵 CC 是 n \times kn×k 阶的,且 C[i][j] = A[i][0] \times B[0][j] + A[i][1] \times B[1][j] + …… +A[i][m-1] \times B[m-1][j](C[i][j]C[i][j]=A[i][0]×B[0][j]+A[i][1]×B[1][j]+……+A[i][m−1]×B[m−1][j](C[i][j] 表示 CC 矩阵中第 ii 行第 jj 列元素)。

输入格式

第一行为 n, m, kn,m,k,表示 AA 矩阵是 nn 行 mm 列,BB 矩阵是 mm 行 kk 列,n, m, kn,m,k 均小于 100100;

然后先后输入 AA 和 BB 两个矩阵,AA 矩阵 nn 行 mm 列,BB 矩阵 mm 行 kk 列,矩阵中每个元素的绝对值不会大于 10001000。

输出格式

输出矩阵 CC,一共 nn 行,每行 kk 个整数,整数之间以一个空格分开。

Sample Input

3 2 3
1 1
1 1
1 1
1 1 1
1 1 1

Sample Output

2 2 2
2 2 2
2 2 2
#include<stdio.h>
int main(){
	int A[100][100],B[100][100],C[100][100]={0};
	int n,m,k,i,j,t;
	scanf("%d%d%d",&n,&m,&k);
	for(i=0;i<n;i++){
		for(j=0;j<m;j++){
			scanf("%d",&A[i][j]);
		}
	}
	for(i=0;i<m;i++){
		for(j=0;j<k;j++){
			scanf("%d",&B[i][j]);
		}
	}
	for(i=0;i<n;i++){
		for(j=0;j<k;j++){
			for(t=0;t<m;t++){
				C[i][j]=C[i][j]+A[i][t]*B[t][j];
			}
			printf("%d ",C[i][j]);
		}
		printf("\n");	
	}
	return 0;
} 

E - Bash游戏

有一堆石子共有N个。A B两个人轮流拿,A先拿。每次最少拿1颗,最多拿K颗,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N和K,问最后谁能赢得比赛。

例如N = 3,K = 2。无论A如何拿,B都可以拿到最后1颗石子。

Input

第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 10000) 第2 - T + 1行:每行2个数N,K。中间用空格分隔。(1 <= N,K <= 10^9)

Output

共T行,如果A获胜输出A,如果B获胜输出B。

Sample Input

4
3 2
4 2
7 3
8 3

Sample Output

B
A
A
B
#include<stdio.h>
int main()
{
   int N,K;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&N,&K);
        if(N%(K+1))
        printf("A\n");
        else
        printf("B\n");
    }
}

F - 取石子游戏

有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。

Input

输入包含若干行,表示若干种石子的初始情况,其中每一行包含两个非负整数a和b,表示两堆石子的数目,a和b都不大于1,000,000,000。

Output

输出对应也有若干行,每行包含一个数字1或0,如果最后你是胜者,则为1,反之,则为0。

Sample Input

2 1
8 4
4 7

Sample Output

0
1
0
#include <stdio.h>
#include <math.h>
#include <string.h>
const double Gsr=(1+sqrt(5.0))/2;
void swap(int *a,int *b)
{
	int t=*b;
	*b=*a;
	*a=t;
}
int main()
{
	int a,b;
	while(~scanf("%d%d",&a,&b))
	{
		if(a>b)
		{
			swap(&a,&b);
		}
		if(a == (int)(Gsr*(b-a))) //奇异局势,先手输
			puts("0");
		else
			puts("1");
	}
	return 0;
}

G - Matches Game

这是一个简单的游戏。在这个游戏中,有几堆火柴和两名玩家。这两个玩家轮流进行。在每一轮中,玩家可以选择一堆并从堆中取出任意数量的火柴(当然,取出的火柴数量不能为零,也不能大于所选堆中的火柴数量)。如果一名玩家取完火柴后,没有剩下火柴,该玩家就是赢家。假设这两个玩家都会作出最优决策。你的工作是判断先手玩家能否赢得比赛。

Input

输入由几行组成,每行中都有一个测试用例。 在一行的开头,有一个整数M(1<=M<=20),它是火柴堆的数量。然后是M个不大于10000000的正整数。这些M个整数表示每堆中的火柴数。

Output

对于每个测试用例,如果第一个玩家获胜,在一行中输出“Yes”,否则输出“No”。

Sample Input

2 45 45
3 3 6 9

Sample Output

No
Yes
#include <bits/stdc++.h>
using namespace std;
int main(){
	int m,n;
	while(scanf("%d",&m)!=EOF){
		int mid;
		for(int i=0;i<m;i++){
			cin>>n;
			if(i==0){
				mid=n;
				continue;
			}

			mid^=n;
		}
		if(!mid){
			cout<<"No"<<endl;
		}else cout<<"Yes"<<endl;
	}
	return 0;
}

H - 互质数的个数(一)

这里我们定义 \varphi(n)φ(n) 表示所有小于等于 nn 与 nn 互质数的个数。

例如 \varphi(10) = 4φ(10)=4,因为我们可以在 1 \sim 101∼10 中找到 1,3,7,91,3,7,9 与 1010 互质。

输入格式

第一行输入一个整数 tt,表示测试数据组数。

接下来 tt 行,每行有一个整数 nn。

输出格式

对于每组测试数据输出 \varphi(n)φ(n) 。

数据范围

1 \le t \le 100, 1 \le n \le 10^{10}1≤t≤100,1≤n≤1010。

Sample Input

3
2
10
100

Sample Output

1
4
40
#include<stdio.h>
#include<math.h>

int huzhi(int a, int b) {
	int  t;
	if (a < b) {
		t = a;
		a = b;
		b = t;
		
	}
	while (a % b) {
		t = b;
		b = a % b;
		a = t;
	}
	return b;
}

int main() {
	int t, n;
	scanf("%d", &t);
	for (int i = 0; i < t; i++) {
		 int count = 0;
		scanf("%d", &n);
		for (int j =1; j<=n; j++) {
			if ( huzhi(n, j)==1)
				count++;
		}
		printf("%d", count);
	}
	return 0;
}

 超时?

#include<stdio.h>
#include<math.h>

long long int fun(long long int n) {
	long long int t = n, i, m;
	for (i = 2; i * i < n; i++) {
		
		if (n % i == 0) {
			t = (t / i) * (i - 1);
			while (n % i == 0) {
				n /= i;
			}
		}
	}
	if (n > 1) t = t / n * (n - 1);
	return t;
}

int main() {
	long long int N, i, n, count;
	scanf("lld", &N);
	for (i = 0; i < N; i++) {
		scanf("%lld", &n);
		count = fun(n);
		printf("%lld\n", count);
	}
	return 0;
}

用欧拉函数解决超时问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值