题目描述
约数个数
p q {p}^{q} pq表示p的q次方,正整数M可以分解为M=( p 1 a 1 {p1}^{a1} p1a1)( p 2 a 2 {p2}^{a2} p2a2)( p 3 a 3 {p3}^{a3} p3a3)……( p n a n {pn}^{an} pnan)的形式,其中p1,p2……pn为质数(大于1并且只能被1和自身整除的数叫做质数)。a1,a2……an为整数。例如18=( 2 1 {2}^{1} 21)( 3 2 {3}^{2} 32),45=( 3 2 {3}^{2} 32)( 5 1 {5}^{1} 51)。
给出n和一个质数g,以及正整数M分解后的形式,求M的所有约数中,有多少能被g整除。
输入
第一行 两个数 n和g。 0
保证对于任意的i,j(i != j) ,pi != pj
输出
一个数
表示M的所有约数中,有多少能被g整除。
样例输入
2 3
3 5
2 2
样例输出
6
题解:乘法原理
若将正整数a分解成质因数pi(i=1,2,…,n)的连乘积时,其中质因数pi的个数是ai(i=1,2,…,n),则正整数a的不同的正因数的个数是(a1+1)×(a2+1)×…×(an+1).
由于g是质数,所以若g是给出的质因数之一,我们将g的个数单独拿出来与其他数组合,即得到答案。
#include
#include
using namespace std;
long long a[100],b[100];
int main()
{
int n;
long long g;
scanf("%d%lld",&n,&g);
long long ans=1;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
long long flag=0;//判断g是否为质因数之一
for(int i=1;i<=n;i++)
{
scanf("%lld",&b[i]);
if(a[i]!=g)
{
ans=ans*(b[i]+1);
}
else
{
flag=1;
ans=ans*b[i];
}
}
printf("%lld",ans*flag);
return 0;
}
折纸达人
题目描述
小明最近对折纸很感兴趣,他想知道一张正方形的纸在多次折叠以后沿纸的中线用剪刀将其剪开能得到多少张纸?
输入
第一行一个整数t,表示一共有t组数据(1 <= t <= 100)
每组输入数据包括三行
第一行为一个整数n,表示有n次操作(1 <= n <= 10^5)
第二行为n个大写字母(四种情况L,R,T,B L表示从左向右折 R表示从右向左折 T表示从上向下折 B表示从下向上折)
第三行为两个字母(四种情况 LR,RL,TB,BT LR表示从左向右剪 RL表示从右向左剪 TB表示从上往下剪 BT表示从下往上剪)
输出
输出一个整数表示能得到的纸的数目
答案可能过大 需要对1000000007 (1e9+7)取模
样例输入
2
2
BB
LR
1
R
LR
样例输出
5
2
题解:根据实际情况,无论怎么样上下折叠,剪开后得到的纸的数量是一样的,左右亦然。然后每对折一次,最后剪开得到的数量会翻倍,同时注意剪的方式。
#include
#include
using namespace std;
const long long mod=1e9+7;
long long ksm(long long a,long long b)
{
if(b==0)
{
return 1;
}
long long ans=ksm(a,b/2);
ans=((ans%mod)*(ans%mod))%mod;
if(b%2==1)
{
ans=((ans%mod)*(a%mod))%mod;
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
long long zy=0,sx=0;
for(int i=1;i<=n;i++)
{
char x;
cin>>x;
if(x=='L'||x=='R')
{
zy++;
}
if(x=='T'||x=='B')
{
sx++;
}
}
string x;
cin>>x;
if(x=="LR"||x=="RL")
{
printf("%lld\n",ksm(2,sx)+1);
}
if(x=="TB"||x=="BT")
{
printf("%lld\n",ksm(2,zy)+1);
}
}
return 0;
}