目录:
A - 双色Hanoi塔问题
B - 进制转换
C - 质数中的质数
D - 王小二切饼
E - 组合数的计算
F - 完美字符串
G - 取数字问题
H - 皮卡丘的伙伴是?
思路:
<1>把n-1个盘子借助b柱子 从a柱子上移到c柱子上 所以move(n-1,a,c,b) 递归实现
<2>把最后一个 也是最大的盘子移到b上 也就是两个move()中间夹着的那一句 // move(原柱子,目标柱子,借助柱子)
<3>把n-1个盘子借助a柱子 从c柱子上移到b柱子上 所以move(n-1,c,b,a) 递归实现
#include
using namespace std;
void move(int n, char a, char b, char c);
int main()
{
int n;
cin >> n;
move(n, 'A', 'B', 'C');
cout << endl;
return 0;
}
void move(int n, char a, char b, char c)
{
if (n == 1)
printf("%d %c %c\n", n, a, b);
else
{
move(n - 1, a, c, b);
printf("%d %c %c\n", n, a, b);
move(n - 1, c, b, a);
}
}
特别注意:n=0的时候
#include
using namespace std;
int main()
{
long long n;
int r;
char s[6] = {'A', 'B', 'C', 'D', 'E', 'F'};
while (~scanf("%lld %d", &n, &r))
{
int cnt = 0, flag = 0;
char str[100000];
if (n < 0)
{
n = abs(n);
flag = 1;
}
else if (n == 0)
flag = 2;
for (int i = 0;; i++)
{
if (n == 0)
break;
int t = n % r;
if (t >= 10)
str[i] = s[t - 10];
else
str[i] = t + '0';
n /= r;
cnt++;
}
if (flag == 2)
printf("0");
else if (flag == 1)
{
printf("-");
for (int i = cnt - 1; i >= 0; i--)
putchar(str[i]);
}
else
{
for (int i = cnt - 1; i >= 0; i--)
putchar(str[i]);
}
printf("\n");
}
return 0;
}
思路:
埃筛 筛素数
#include
using namespace std; //埃筛
int p, prime[10000001];
bool isprime[10000001];
void sieve()
{
p = 1;
for (int i = 0; i <= 1e7; i++)
isprime[i] = true;
isprime[0] = false, isprime[1] = false;
for (int i = 2; i <= 1e7; i++)
{
if (isprime[i])
{
prime[p++] = i;
for (int j = 2 * i; j <= 1e7; j += i)
isprime[j] = false;
}
}
}
int main()
{
int n, i;
sieve();
while (~scanf("%d", &n))
{
for (i = 1; i < p; i++)
{
if (prime[i] >= n && isprime[i])
break;
}
printf("%d\n", prime[i]);
}
return 0;
}
#include
using namespace std;
int main()
{
int dp[111];
int n;
cin >> n;
dp[1] = 2;
for (int i = 2; i <= n; i++)
dp[i] = dp[i - 1] + i;
cout << dp[n] << endl;
return 0;
}
解法一:
思路:
把分子上能够整除2的数 换成2 分母中约去相应的值
例如
分子上有个 40 40%2==0 分子上一定有个20与之对应
把分母上的40换成2 分子上的20换为1 分别存入对应的数组中
#include
using namespace std;
int arr[41];
int brr[41];
void c(int a, int b)
{
for (int i = 0; i < 41; i++) //注意一定要初始化否则每进行一次高精运算的下一次运算会错
{
arr[i] = 0;
brr[i] = 0;
}
for (int i = 1; i <= b; i++)
arr[i] = i;
int cnt = 1;
double m = 1.0, n = 1.0;
for (int i = a; cnt <= b; i--)
{
brr[i] = i;
cnt++;
if (brr[i] % 2 == 0 && arr[brr[i] / 2] > 1)
{
arr[brr[i] / 2] = 1;
brr[i] = 2;
}
m *= brr[i];
}
for (int i = 1; i <= b; i++)
n *= arr[i];
printf("%.0lf\n", m / n);
}
int main()
{
int n, a, b;
scanf("%d", &n);
while (n--)
{
scanf("%d %d", &a, &b);
if (a < b)
printf("0\n");
else if (a / 2 < b)
c(a, a - b);
else
c(a, b);
}
return 0;
}
解法二:
思路:
牢记组合数递推公式 c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
#include //组合数公式
using namespace std;
long long c[45][45];
int main()
{
int n, a, b;
scanf("%d", &n);
for (int i = 0; i <= 41; i++)
c[i][0] = 1;
for (int i = 1; i <= 41; i++)
for (int j = 1; j <= i; j++)
c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
while (n--)
{
scanf("%d %d", &a, &b);
printf("%lld\n", c[a][b]);
}
return 0;
}
#include
using namespace std;
int main()
{
char str[10001];
while (gets(str))
{
int ans = 26, a[100] = {0};
for (int i = 0; i < strlen(str); i++)
{
if (str[i] >= 'a' && str[i] <= 'z')
str[i] -= 32;
a[str[i]]++;
}
int sum = 0;
sort(a + 65, a + 91);
for (int i = 90; i >= 65; i--)
{
if (a[i] == 0)
continue;
else
{
sum += a[i] * ans;
ans--;
}
}
printf("%d\n", sum);
}
return 0;
}
思路:
暴力搜索:递归实现
在i < m 和 j < n的前提下 搜索对应数的 右侧的数 和下方的数
注意:有多种路线走到右下方 所以有多个sum 所以sum
当 搜索到右下方数字时候 如果sum>0 返回sum 否则 满足条件输出-1
#include
using namespace std; //暴力搜索
int m, n, a[11][11];
int ans = 501966782;
void search(int i, int j, int sum)
{
sum += a[i][j];
if (i < m)
search(i + 1, j, sum);
if (j < n)
search(i, j + 1, sum);
if (i == m && j == n && sum < ans && sum > 0)
ans = sum;
}
int main()
{
scanf("%d%d", &m, &n);
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
scanf("%d", &a[i][j]);
search(1, 1, 0);
if (ans == 501966782)
ans = -1;
printf("%d\n", ans);
return 0;
}
注意:
既不克制也不抵抗时的情况
#include
using namespace std;
int isok(char *s1, char *s2)
{
if (strcmp("Water", s1) == 0)
{
if (strcmp("Fire", s2) == 0)
return 1;
if (strcmp("Grass", s2) == 0 || strcmp(s1, s2) == 0)
return 0;
}
else if (strcmp("Fire", s1) == 0)
{
if (strcmp("Grass", s2) == 0)
return 1;
if (strcmp("Water", s2) == 0 || strcmp(s1, s2) == 0)
return 0;
}
else if (strcmp("Grass", s1) == 0)
{
if (strcmp("Water", s2) == 0)
return 1;
if (strcmp("Fire", s2) == 0 || strcmp(s1, s2) == 0)
return 0;
}
else if (strcmp("Electric", s1) == 0)
{
if (strcmp("Water", s2) == 0)
return 1;
if (strcmp("Grass", s2) == 0 || strcmp(s1, s2) == 0)
return 0;
}
return -1;
}
int main()
{
char s1[10], s2[10], cc[10];
float a, b, c;
while (~scanf("%s %s", s1, s2))
{
scanf("%f %f %s", &a, &b, cc);
a *= 1.5;
if (isok(s1, s2) == 1)
{
a *= 2;
if (strcmp("Normal", cc) == 0 || isok(cc, s2) == -1)
c = 60.0;
else if (isok(cc, s2) == 1)
c = 60 * 2.0;
else if (isok(cc, s2) == 0)
c = 60.0 / 2;
}
else if (isok(s1, s2) == 0)
{
a /= 2;
if (strcmp("Normal", cc) == 0 || isok(cc, s2) == -1)
c = 60.0;
else if (isok(cc, s2) == 1)
c = 60 * 2.0;
else if (isok(cc, s2) == 0)
c = 60.0 / 2;
}
else if (isok(s1, s2) == -1)
{
if (strcmp("Normal", cc) == 0 || isok(cc, s2) == -1)
c = 60.0;
else if (isok(cc, s2) == 1)
c = 60 * 2.0;
else if (isok(cc, s2) == 0)
c = 60.0 / 2;
}
float num[4];
int cnt[4] = {0, 1, 2, 3};
num[cnt[1]] = a, num[cnt[2]] = b, num[cnt[3]] = c;
for (int i = 1; i < 3; i++)
{
for (int j = i + 1; j <= 3; j++)
{
if (num[i] < num[j])
{
float t = num[i];
num[i] = num[j];
num[j] = t;
int o = cnt[i];
cnt[i] = cnt[j];
cnt[j] = o;
}
}
}
printf("%d\n", cnt[1]);
}
return 0;
}