转换字符串
题干:
三种字符串之间的转化,每种转换所花费的时间是2的次数,输出总和。
题解:
模拟+快速幂,注意整数类型使用long long。
快速幂:
任何一个整数都可以表示成二进制的形式,比如你想求10的50次方,50的二进制表示为110010。我们根据10的1次方可以快速的求出10的2次方(进行相乘即可)。由10的2次方可以快速求出10的4次方,由10的4次方可以快速求出10的8次方…。所以这种算法就可以极快的算出a的b次幂,对于10的50次方来说,50转化为二进制共有6位,我们只需要做6次乘法运算即可。
通解公式:
b为偶数:
a
b
=
a
b
/
2
∗
a
b
/
2
a^b=a^{b/2}*a^{b/2}
ab=ab/2∗ab/2
b为奇数:
a
b
=
a
∗
a
b
−
1
a^b=a*a^{b-1}
ab=a∗ab−1
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 1e9+7;
ll ans;
ll qm(ll a, ll b)
{
ll res = 1;
a %= mod;
while(b --) res = res*a%mod;
return res;
}
int main()
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
int n;
scanf("%d", &n);
while(n --)
{
int k;
scanf("%d", &k);
char str1[11] = "", str2[11] = "";
while(k --)
{
scanf("%s", str2);
if(!strcmp(str1, "be_ready") && !strcmp(str2, "implement")) ans = (ans+qm(2, a))%mod;
if(!strcmp(str1, "implement") && !strcmp(str2, "block")) ans = (ans+qm(2, b))%mod;
if(!strcmp(str1, "block") && !strcmp(str2, "implement")) ans = (ans+qm(2, c))%mod;
strcpy(str1, str2);
}
}
printf("%d", (int)ans);
return 0;
}
import java.util.Scanner;
public class Main {
public static long f(long x,long y, long mod) {
long res = 1;
while(y > 0) {
if(y%2 == 1) {
y --;
res = res*x%mod;
} else {
y /= 2;
x = x*x%mod;
}
}
return res;
}
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
long mod = 1000000007;
long sum = 0;
long a = sc.nextLong();
long b = sc.nextLong();
long c = sc.nextLong();
long n = sc.nextLong();
while(n -- > 0) {
StringBuilder x = new StringBuilder("");
StringBuilder y = new StringBuilder("");
int k = sc.nextInt();
while(k -- > 0) {
y = new StringBuilder(sc.next());
String x2 = x.toString();
String y2 = y.toString();
if(x2.equals("be_ready") && y2.equals("implement")) {
sum = (sum + f(2,a,mod))%mod;
} else if(x2.equals("implement") && y2.equals("block")) {
sum = (sum + f(2,b,mod))%mod;
} else if(x2.equals("block") && y2.equals("implement")) {
sum = (sum + f(2,c,mod))%mod;
}
x = new StringBuilder(y2);
}
}
System.out.print(sum);
sc.close();
}
}