A.Dreamoon-and-Stairs
代码
#include<stdio.h>
int main(){
int count = 0;
int n,m;
while (~scanf("%d %d",&n,&m)) {
if(n < m){
printf("-1\n");
continue;
}
count = n/2 + n % 2;
int flag = 1;
if(count % m != 0){
for(int i = 0;i < n/2;i++){
count += 1;
if(count % m == 0){
flag = 0;
printf("%d\n",count);
break;
}
}
if(flag){
printf("-1\n");
}
}
else{
printf("%d\n",count);
}
}
}
B.Dreamoon-and-WiFi
题意
Dream会接收到Drazil发来的一段命令,‘+’表示向正方向走一单位,‘-’表示负方向走一单位,但是因为Wi-Fi问题,所以可能接收不了或者接收错误,所以按照接收到的命令做并且以0.5的概率对没有接收到的命令进行±选择,问 他最后停下的位置于发来的位置相匹配的概率。
题解
因为接收的和发送的命令数量一样,所以只需要判断前后的±数量是否相等。又因为只有两种命令,所以只要确定了一种,另一种也确定了。对于其中一项差值,只需要用数学中的概率计算?数量中可选择的情况数。
代码
#include<stdio.h>
#include<string.h>
#include<math.h>
int main(){
char s1[11];
char s2[11];
int a1 = 0,a2 = 0,b1 = 0,b2 = 0;
int init = 0;
double x = 0;
while (~scanf("%s",s1)) {
a1 = a2 = b1 = b2 = 0;
init = x = 0;
for(int i = 0;i < strlen(s1);i++){
if(s1[i] == '+')
a1++;
else
a2++;
}
scanf("%s",s2);
for(int i = 0;i < strlen(s2);i++){
if(s2[i] == '+')
b1++;
else if(s2[i] == '-')
b2++;
else
init++;
}
//没有问号直接判断两个终点是否一致
if(init == 0){
if(a1 == b1)
x = 1;
else
x = 0;
}
else{
//如果发送的命令其中一个符号小于对应的接收命令符号,不能删所以不满足
if(a1 - b1 < 0 || a2 - b2 < 0)
x = 0;
//问号可被替代的符号只有两种,一种被确定,另一种也确定了
else{
int c1 = 1,c2 = 1;
for(int i = 1;i <= a1 - b1;i++){
c1 *= i;
}
for(int i = init; i > init - a1 + b1;i--){
c2 *= i;
}
x = c2 / c1 / pow(2, init);
}
}
printf("%.12lf",x);
}
}
C.Dreamoon-and-Sums
题意
Dream获得两个整数a,b。如果x可以被b整除并且div(x,b)/mod(x,b)是属于[1,a]的整数,我们就叫x是nice数。求nice数的和,答案可能会很大,所以最后的答案mod(1e9+7)。
题解
代码
#include<stdio.h>
#define MOD 1000000007
using namespace std;
int main(){
long long a,b;
while (~scanf("%lld %lld",&a,&b)) {
long long x = a*(a+1)/2%MOD;
long long y = (x * b % MOD + a) % MOD;
long long z = (y * (b*(b-1)/2%MOD)) % MOD;
printf("%lld\n",z);
}
return 0;
}
E.You-Are-Given-a-Decimal-String…
题解
当题目给出一串字符串时,你需要向里面加0-9的数字,使它能满足x-y计数器(0<=x,y<=9)。我们将给出的串中每两个数字间加的值当作最小路径的过程。所以就需要用floyd计算0-9的最短路径。
代码
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#define Max 0x3f3f3f3f
using namespace std;
int s[11][11];
char flo[2000005];
int operate(int x,int y,long long int n){
//初始化x-y距离为∞
memset(s,Max,sizeof(s));
//当前x-y计数器能得到的两个连续数字位置,距离为1
for(int i = 0;i <= 9;i++){
s[i][(i + x)%10] = 1;
s[i][(i + y)%10] = 1;
}
//计算x-y计数器每两个数之间(如果能到达)的最小距离
for(int k = 0;k <= 9;k++)//因为输出的是最后一位,所以中间值一直在【1,9】内变换
for(int i = 0;i <= 9;i++)
for(int j = 0;j <= 9;j++)
s[i][j]=min(s[i][j],s[i][k]+s[k][j]);
int count = 0;
for(int i = 0;i < n-1;i++){
int ans = s[flo[i] - '0'][flo[i+1] - '0'];
//如果无穷距离,说明无法到达
if(ans == Max){
return -1;
}
//因为最后一步已经存在,所以只加中间步
count += ans - 1;
}
return count;
}
int main(){
long long int n;
while(~scanf("%s",flo)){
n = strlen(flo);
for(int i = 0;i <= 9;i++){
for(int j = 0;j <= 9;j++){
printf("%d ",operate(i, j, n));
}
printf("\n");
}
return 0;
}
}