2017.7.31
1.
题目链接:https://vjudge.net/contest/174587#problem/D
题目:D - 越狱
监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种。如果
相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱
Input
输入两个整数M,N.1<=M<=10^8,1<=N<=10^12
Output
可能越狱的状态数,模100003取余
Sample Input
2 3
Sample Output
6
Hint
6种状态为(000)(001)(011)(100)(110)(111)
自己的想法:最开始以为是一道组合数学问题,只要推出公式,套用就行了。
#include <iostream>
#include"stdio.h"
#include"math.h"
using namespace std;
const long long mod=100003;
long long mi(long long m,long long n)
{
long long sum=1;
for(long long i=1;i<=n;i++)
{
sum*=m;
}
return sum;
}
int main()
{
long long mi(long long m,long long n);
long long n,m;
scanf("%lld%lld",&m,&n);
printf("%lld\n",(mi(m,n)%mod-m*mi(m-1,n-1)%mod)%mod);
return 0;
}
思路:但是后来看到有模100003取余,还要考虑((M^N)%mod-(M*(M-1)^(N-1))%mod)%mod有可能为负数,ans<0,ans+=mod 也可以((M^N)%mod+mod-(M*(M-1)^(N-1))%mod)%mod 即中间加个mod。题解:http://www.cnblogs.com/CXCXCXC/p/4661980.html。后来知道这关系到时间复杂度。要用快速幂法来求m的n次幂。链接:http://www.cnblogs.com/CXCXCXC/p/4641812.html#undefined。
心得体会:1.^在C里面不能用来算幂,要通过for循环来算幂(m的n次幂)
如m=1;
for(int i=1;i<=n;i++)
{
Sum*=m;
}
但是这种做法用的时间比较长。用快速幂法比较方便。
2.快速幂法
知识点:x&1==0为偶,x&1==1为奇。
>>运算比较单纯,二进制去掉最后一位
int poww(int a,int b){
int ans=1,base=a;
while(b!=0)
{
if(b&1!=0)//b为奇数
ans*=base;
base*=base;
b>>=1;
}
return ans;
}
源代码:
#include <iostream>
#include"stdio.h"
using namespace std;
typedef long long ll;
const int mod=100003;
ll m,n;
ll sum;
ll mi(ll a,ll b)
{
ll ans=1;
while(b!=0)
{
if(b&1)ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans%mod;}
int main()
{
cin>>n>>m; sum=(mi(m,n)+mod-(m*mi(m-1,n-1))%mod)%mod;
cout<<sum<<endl;
return 0;
}
2.
A - Train Problem II
As we all know the Train Problem I, the boss of the Ignatius Train Station want to know if all the trains come in strict-increasing order, how many orders that all the trains can get out of the railway.
Input
The input contains several test cases. Each test cases consists of a number N(1<=N<=100). The input is terminated by the end of file.
Output
For each test case, you should output how many ways that all the trains can get out of the railway.
Sample Input
1
2
3
10
Sample Output
1
2
5
16796
Hint
The result will be very large, so you may not process it by 32-bit integers.
自己的想法
//看m,n是否有公因子。
#include <iostream>
#include"stdio.h"
using namespace std;
long long m,n;
int main()
{
int t;
long long x,i;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&m,&n);
x=m>n?n:m;
if((m==1||m==2)&&(n==1||n==2)&&m!=n)
printf("NO\n");
else if(m==n)
printf("YES\n");
else for(i=2;i<x;i++)
{
if(m%i==0&&n%i==0)
{printf("YES\n");break;}
}
if(i==x)printf("NO\n");
}
return 0;
}
题解:用辗转相除法高效算公因子
即用除数 取余 余数;
http://blog.csdn.net/lttree/article/details/16348965
源代码:
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
int m,n,t;
int k;
scanf("%d",&t);
for(;t>0;--t)
{
scanf("%d%d",&m,&n);
while(n!=0)
{
k=m%n;
m=n;
n=k;
}
if(m!=1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}