【算法笔记】 简单数学问题的题解

1.连续数和

题目描述

一个正整数有可能可以被表示为n(109>=n>=2)个连续正整数之和,如:
15=1+2+3+4+5
15=4+5+6
15=7+8
根据输入的任何一个正整数,找出符合这种要求的所有连续正整数序列。

输入格式

一个正整数。

输出格式

输出符合题目描述的全部正整数序列,每行一个序列,每个序列都从该序列的最小正整数开始、以从小到大的顺序打印。如果结 果有多个序列,按各序列的最小正整数的大小从小到大打印各序列。此外,序列不允许重复,序列内的整数用一个空格分隔。如果没有符合要求的序列,输出 “NONE”。

样例数据

input1
15

output1
1 2 3 4 5
4 5 6
7 8

input2
16

output2
NONE

扫描二维码关注公众号,回复: 2194901 查看本文章

必然有一串数等于n,设这串数字头为a,尾为b;
则根据等差数列公式:和=(首项+末项)*项数/2;
因此可得,(a+b)(b-a+1)/2=n
化简,得:(a+b)(b-a+1)=2n
显然,a+b 和 b-a+1 都为整数且是2n的因数
因此我们便只要枚举2n的因数i即可
接着,我们设xy=2n,就可以得到方程组:
【a+b=x
b-a+1=y】
解这个方程组,得:b=(x+y-1)/2,a=x-b(当x,y为参数时)
然后枚举i是,1.设x=i;2.设y=i 则进行两次操作求合法的a和b就可以了
参考代码:

#include<bits/stdc++.h>
using namespace std;
int n,t,flag,tmp=0;
struct s{int l,r;}ans[100000]={};
inline bool cmp(s x,s y){return x.l<y.l;}
void tries(int x,int y)
{
    if ( (x+y-1)%2 == 1 ) return;
    int b=(x+y-1)/2;
    int a=x-b;
    if ((a+b)*(b-a+1)/2==n&&a>0&&b>0)
    {
        flag=1;
        ans[++tmp].l=a;
        ans[tmp].r=b;
    }
}
int main()
{
    cin>>n;
    t=2*n;
    for (int i=2;i<=sqrt( t );i++)
    if (t%i==0)
    {
        tries(i,t/i);
        tries(t/i,i);
    }
    if (flag==0) cout<<"NONE";
    sort(ans+1,ans+tmp+1,cmp);
    for (int i=1;i<=tmp;i++)
    {
        for (int j=ans[i].l;j<ans[i].r&&j;j++)
            cout<<j<<' ';
        cout<<ans[i].r<<endl;
    }
    return 0;
}

2.越狱

题目描述

监狱有连续编号为1..n的n个房间,每个房间关押一个犯人。有m种宗教,每个犯人可能信仰其中一种。如果相邻房间的犯人信仰的宗教相同,就可能发生越狱。求有多少种状态可能发生越狱。

输入格式

输入两个整数m和n,1≤m≤10 8
108
,1≤n≤10 12
1012

输出格式

可能越狱的状态数,模100003取余。

样例数据

input
2 3

output
6

样例说明

6 种状态为:(000)(001)(011)(100)(110)(111)

数据规模与约定

时间限制:1s
1s

空间限制:256MB
256MB

求可能发生越狱,再根据:可能发生数+不可能发生数=总数,得:所求答案=总数-不可能发生数
总数=m^n
不可能发生数=m*(m-1)^(n-1)
即,ans=m^n-m*(m-1)^(n-1)
由于数据过大,需要快速幂
有序减法取模,请及时加上Mod,且即使取模即可
参考代码:

#include<bits/stdc++.h>
using namespace std;
const long long Mod=100003;
long long n,m;
long long QPower(long long a,long long b)
{
    long long temp=b,s=a,ans=1;
    while (temp>0)
    {
        if (temp%2==1) ans=ans*s%Mod;
        s=s*s%Mod;
        temp/=2;
    }
    return ans;
}
int main()
{
    cin>>m>>n;
    cout<<(QPower(m,n)%Mod-m*(QPower(m-1,n-1)%Mod)%Mod+Mod)%Mod;
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/ronaldo7_zyb/article/details/80945454