牛客0x01 基本算法-位运算 B题Raising Modulo Numbers

2 篇文章 0 订阅

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

People are different. Some secretly read magazines full of interesting girls' pictures, others create an A-bomb in their cellar, others like using Windows, and some like difficult mathematical games. Latest marketing research shows, that this market segment was so far underestimated and that there is lack of such games. This kind of game was thus included into the KOKODáKH. The rules follow: 

Each player chooses two numbers Ai and Bi and writes them on a slip of paper. Others cannot see the numbers. In a given moment all players show their numbers to the others. The goal is to determine the sum of all expressions{Ai}^{Bi}Ai​Bi​from all players including oneself and determine the remainder after division by a given number M. The winner is the one who first determines the correct result. According to the players' experience it is possible to increase the difficulty by choosing higher numbers. 
 

You should write a program that calculates the result and is able to find out who won the game. 
题目意思大概是:
有一个这样的游戏,规则是:
每个玩家选择两个数字‎Ai‎和‎Bi‎,并把它们写在纸条上。其他人看不到这些数字。在给定的时刻,所有玩家都向其他人展示他们的号码。目标是确定所有表达式的总和‎‎{Ai}^{Bi}‎,‎​‎从包括自己在内的所有玩家中,确定除以给定数字M后的余数。获胜者是第一个确定正确结果的人。根据玩家的经验,可以通过选择更高的数字来增加难度。‎
 

‎你应该编写一个程序来计算结果,并能够找出谁赢得了比赛

输入描述:

The input consists of Z assignments. The number of them is given by the single positive integer Z appearing on the first line of input. Then the assignements follow. Each assignement begins with line containing an integer M (1≤M≤45000). The sum will be divided by this number. Next line contains number of players H(1≤H≤45000). Next exactly H lines follow. On each line, there are exactly two numbers Ai and Bi separated by space. Both numbers cannot be equal zero at the same time.

大概意思就是第一行输入一个比赛个数z,接下来的每个任务都是一个整数M(1≤M≤45000)开头,下面的总和将对它取余,接下来输入玩家人数H(1≤H≤45000),然后输入H行每行两个数Ai,Bi,并且两个数不能同时为0。

输出描述:

For each assingnement there is the only one line of output. On this line, there is a number, the result of expression ({A1}^{B1}+{A2}^{B2}+ ... +{AH}^{BH}) mod M.

大概意思是每个比赛只有一行输出,输出的是 ({A1}^{B1}+{A2}^{B2}+ ... +{AH}^{BH}) mod M的值。

示例1

输入

3
16
4
2 3

4 5
5 6
36123
1
2374859 3029382
17
1
3 18132

输出

2
13195
13

解题思路:

      这道题的主要难点在于多个幂的计算以及数据可能溢出,故我们可以写一个函数来快速进行幂计算,定义一个新变量t = 1%M,然后写一个循环Bi为0结束循环,将Bi用二进制数依次判断每一位是否为1,若为1则t乘以Ai同时为了防止数据溢出对M取余,接着Bi右移一位(相当于除以2),同时对Ai平方,这样就大大减少了代码的运行时间,注意在每次调用该函数后都要对M取余。

举个例子:Ai 为2 ,Bi 为8 

Bi的二进制位为1000,进入循环中Bi的第一位为0,t不变,Ai就等于 2^2 ,Bi右移一位还是0,t不变,Ai变为 2^4,Bi再右移一位到第三位还是0,t不变,Ai变为 2^8,Bi再右移一位第四位为1,t 就为 2^8,Bi没法右移了就结束循环,这样原本要计算8次现在只需要3次就行,后面指数增长也更快,对大数据这种方法更快、便捷。

代码:

#include<iostream>
using namespace std;
typedef long long ll; //为long long 取别名ll 
ll pow(ll m,ll x,ll y) {  //快速幂计算,x,y分别为Ai,Bi 
	ll t=1%m;  //对m取余是为了避免y为0同时m为1没有进入循环
	while(y) {
		if(y&1) t=t*x%m;  //判断y是否为1 
		x=x*x%m;
		y>>=1;    //y转换成二进制右移一位 
	}
	return t;
}
int main() {
	ll z,Ai,Bi,i,j,m,h,s;
	cin>>z; //输入比赛个数 
	for(i=0; i<z; i++) {
		cin>>m>>h; //输入取余数m和比赛人数h 
		s=0;  //重置s 
		for(j=0; j<h; j++) {
			cin>>Ai>>Bi; 
			s=(s+pow(m,Ai,Bi))%m; //防止数据溢出,每次都对m取余 
		}
		cout<<s<<endl; //每个比赛输出一次 
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值