气球消消乐
蒜头君有 n 只气球,蒜头君把气球排成一排。初始时,气球都是白色,现在蒜头君想用 m 种颜色给气球涂色,如果相邻的气球的颜色相同,这 2 个气球会发生消消乐,蒜头君希望你求出会发生消消乐的涂色方法有多少种。最后答案对 10^{12}+7 取模。
输入格式
输入两个整数 n (1≤n≤12),m (1≤m≤12)
输出格式
输出一个整数表示答案。
样例输入1
2 2
样例输出1
2
样例输入2
3 4
样例输出2
28
思路:发生消除的事件数等于所有事件数(m^n),减去不发生消消乐的次数(m*((m-1)^(n-1))),即第一个气球可以涂m种颜色,剩下的气球只能涂m -1种颜色(要与前一个气球不同),采用快速幂和快速乘进行计算
mul_mod : 计算 a * b % mod的值
pow_mod :计算 a ^ b % mod的值
#include <cstdio>
#include <iostream>
using namespace std;
const long long mod = 1e12 + 7;
long long mul_mod(long long a,long long b){
long long res = 0;
while(b > 0){
if(b & 1){
res = (res + a) % mod;
}
a = (a + a) % mod;
b >>= 1;
}
return res;
}
long long pow_mod(long long a,long long b){
long long res = 1;
while(b > 0){
if(b & 1){
res = mul_mod(res,a);
}
a = mul_mod(a,a);
b >>= 1;
}
return res;
}
int main(){
long long n,m;
cin >> n >> m;
cout << (pow_mod(m,n) - mul_mod(pow_mod(m-1,n-1),m)+mod) % mod;
return 0;
}
跳石头
一年一度“跳石头”比赛又要开始了!
这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有 N 块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。
为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走 M 块岩石(不能移走起点和终点的岩石)。
输入格式
输入第一行包含三个整数 L,N,M,分别表示起点到终点的距离,起点和终点之间的岩石数,以及组委会至多移走的岩石数。
接下来 N 行,每行一个整数,第 ii 行的整数 Di(0<Di<L) 表示第 i 块岩石与 起点的距离。这些岩石按与起点距离从小到大的顺序给出,且不会有两个岩石出现在同一个位置。
输出格式
输出只包含一个整数,即最短跳跃距离的最大值。
数据范围
对于 2020% 的数据,0≤M≤N≤10。
对于 5050% 的数据,0≤M≤N≤100。
对于 100100% 的数据,0≤M≤N≤50,000,
样例说明
将与起点距离为 2 和 14 的两个岩石移走后,最短的跳跃距离为 4(从与起点距离 17 的岩石跳到距离 21 的岩石,或者从距离 21 的岩石跳到终点)。
样例输入复制
25 5 2
2
11
14
17
21
样例输出复制
4
思路:二分答案,检查答案是否可行,关键在Check函数
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int a[100001],l,m,n,i;
//搜索答案,类似贪心节约用电
//最短的最长,最大的最小:考虑二分答案
bool check(int k){
int cnt = 0,last = 0;
for(int i = 0;i < m;i++){
if(a[i] - last >= k){ //注意是大于等于
last = a[i];
}
else{
cnt++;
}
}
if(cnt > n){
return false;
}
return true;
}
int main(){
cin >> l >> m >> n;
for(i = 0;i < m;i++){
cin >> a[i];
}
int left = 0,right = l,mid,ans = 0;
a[i] = l;
while(left <= right){
mid = (left + right) / 2;
if(check(mid)){
left = mid + 1;
ans = mid;
}
else{
right = mid - 1;
}
//cout << mid << endl;
}
cout << ans;
return 0;
}