9.2 斐波那契数列
#include <cstdio>
int fib[25] = { 0 };
void Cal() {
fib[1] = 1;
fib[2] = 1;
for (int i = 3; i <= 20; i++)
fib[i] = fib[i - 1] + fib[i - 2];
}
int main() {
Cal();
int n;
scanf("%d", &n);
while (n--) {
int t;
scanf("%d", &t);
printf("%d\n", fib[t]);
}
return 0;
}
9.3 二叉树
题目分类在递归里,一开始递归变递推方法做的,结果超时。只能用笨方法做啦。
#include <cstdio>
#include <cmath>
int main() {
long long n, m, left, count;
while (1) {
scanf("%lld %lld", &m, &n);
if (m == 0 && n == 0)
break;
count = 0;
int i = 0;
left = m;
while (m <= n) {
count += int(pow(2.0, i++));
m = m * 2 + 1;
left = left * 2;
}
while (left <= n) {
count++;
left++;
}
printf("%lld\n", count);
}
return 0;
}
9.4 逆波兰表达式
#include <iostream>
#include <stack>
#include <string.h>
#include <stdlib.h>
#include <math.h>
using namespace std;
int main() {
stack<double> s;
char str[1000][10] = {};
int i = 0;
while (cin >> str[i])
i++;
i--;
for (i; i >= 0; i--) {
if (str[i][0] != '+'&&str[i][0] != '-'&&str[i][0] != '*'&&str[i][0] != '/')
s.push(atof(str[i]));
if (str[i][0] == '+') {
double a = s.top();
s.pop();
double b = s.top();
s.pop();
double c = b + a;
s.push(c);
}
if (str[i][0] == '-') {
double a = s.top();
s.pop();
double b = s.top();
s.pop();
double c = a - b;
s.push(c);
}
if (str[i][0] == '*') {
double a = s.top();
s.pop();
double b = s.top();
s.pop();
double c = b * a;
s.push(c);
}
if (str[i][0] == '/') {
double a = s.top();
s.pop();
double b = s.top();
s.pop();
double c = a / b;
s.push(c);
}
}
double ans = s.top();
printf("%f", ans);
return 0;
}
9.5 放苹果
#include <cstdio>
int Cal(int n, int m) {//n是苹果数量,m是盘子数量
//如果m>n,必定有m-n个盘子空着,去掉他们对摆放苹果方法数目不产生影响
//如果n<=m,不同的方法可以分为两类,即至少一个盘子空着或者所有的盘子都有苹果
if (n == 0 || m == 1)
return 1;
if (m > n)
return Cal(n, n);//盘子比苹果数多
else
return Cal(n, m - 1) + Cal(n - m, m);
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n, m;
scanf("%d %d", &n, &m);
printf("%d\n", Cal(n, m));
}
return 0;
}
9.6 红与黑
BFS~
#include <cstdio>
#include <queue>
#include <string.h>
using namespace std;
int row, col;
char maze[25][25];
bool Visit[25][25] = { false };
int X[4] = { 0,0,1,-1 };
int Y[4] = { 1,-1,0,0 };
int Count = 0;
struct node {
int x, y;
}S, temp;
bool Judge(int x, int y) {
if (x < 0 || x >= row || y < 0 || y >= col)
return false;
if (maze[x][y] == '#' || maze[x][y] == '@')
return false;
if (Visit[x][y] == true)
return false;
return true;
}
void BFS() {
queue<node> q;
q.push(S);
while (!q.empty()) {
node t = q.front();
q.pop();
if (maze[t.x][t.y] == '.')
Count++;
for (int i = 0; i < 4; i++) {
int newx = t.x + X[i];
int newy = t.y + Y[i];
if (Judge(newx, newy)) {
temp.x = newx;
temp.y = newy;
q.push(temp);
Visit[temp.x][temp.y] = true;
}
}
}
}
int main() {
while (1) {
scanf("%d %d", &col, &row);
if (row == 0 && col == 0)
break;
Count = 1;
memset(maze, '#', sizeof(maze));
memset(Visit, false, sizeof(Visit));
for (int i = 0; i < row; i++) {
scanf("%s", maze[i]);
for (int j = 0; j < col; j++) {
if (maze[i][j] == '@') {
S.x = i;
S.y = j;
}
}
}
BFS();
printf("%d\n", Count);
}
return 0;
}
9.7 八皇后问题
啊啊啊我独立地写出来八皇后问题了!!!好激动!!!!
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
int ans[92][8] = { 0 };//存放结果
int hang[8] = { 0 };//hang存的是,这一行对应的列数
int Count = 0;
void DFS(int x) {//x表示行
if (x == 8) {//到第九行了,说明这个可以
for (int i = 0; i < 8; i++)
ans[Count][i] = hang[i];
Count++;
}
else {//还没到第九行,枚举判断
for (int j = 0; j < 8; j++) {//j是列,看看能不能放
int i = 0;
for (i; i < x; i++) {
if (hang[i] == j || abs(j - hang[i]) == abs(x - i))
break;
}
if (i == x) {
hang[x] = j;
DFS(x + 1);
}
}
}
}
int main() {
int n;
scanf("%d", &n);
DFS(0);
while (n--) {
int t;
scanf("%d", &t);
for (int i = 0; i < 8; i++)
printf("%d", ans[t - 1][i]+1);
printf("\n");
}
return 0;
}
9.8 木棒问题
第二遍了还不会做……
#include <cstdio>
#include <stdlib.h>
#include <algorithm>
using namespace std;
int sticks[100];
bool used[100] = { false };
bool cmp(int a, int b) {
return a > b;
}
bool Concatenate(int totalSticks, int unusedSticks, int left, int len) {
//totalSticks是木棒总数
//unusedSticks是未被拼接到的长度为len的原始木棒中的木棒数目
//left是正在拼接的木棒的剩余长度
//len是正在尝试的原始木棒的长度
if (unusedSticks == 0 && left == 0)
return true;
if (left == 0)
left = len;
for (int i = 0; i < totalSticks; i++) {
if (used[i] == true)
continue;
if (sticks[i] > left)
continue;
used[i] = true;
if (Concatenate(totalSticks, unusedSticks - 1, left - sticks[i], len))
return true;
used[i] = false;
if (sticks[i] == left || left == len)
break;
}
return false;
}
int main() {
while (1) {
int n;
scanf("%d", &n);
if (n == 0)
break;
int sum = 0;
fill(used, used + n, false);
for (int i = 0; i < n; i++) {
scanf("%d", &sticks[i]);
sum += sticks[i];
}
sort(sticks, sticks + n, cmp);
int len = sticks[0];
for (int i = len; i <= sum; i++) {
if (sum%i != 0)
continue;
if (Concatenate(n, n, 0, i)) {
printf("%d\n", i);
break;
}
}
}
return 0;
}
10.1 数字三角形
#include <cstdio>
#include <algorithm>
using namespace std;
int dp[110][110] = { 0 };
int Tri[110][110];
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++)
scanf("%d", &Tri[i][j]);
}
for (int i = 0; i < n; i++)
dp[n - 1][i] = Tri[n - 1][i];
for (int i = n - 2; i >= 0; i--) {
for (int j = 0; j <= i; j++) {
dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + Tri[i][j];
}
}
printf("%d", dp[0][0]);
return 0;
}
10.3 最长上升子序列
#include <cstdio>
#include <algorithm>
using namespace std;
int a[1010] = { 0 };
int dp[1010] = { 0 };
int main() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 1; i <= n; i++) {
dp[i] = 1;
for (int j = 1; j < i; j++) {
if (a[i] > a[j] && dp[j] + 1 > dp[i])
dp[i] = dp[j] + 1;
}
}
int ans = -1;
for (int i = 1; i <= n; i++)
ans = max(ans, dp[i]);
printf("%d", ans);
return 0;
}
10.4 Help Jimmy
嗯还是不会做,又抄了一遍书。
#include <cstdio>
#include <memory.h>
#include <algorithm>
using namespace std;
const int MAXN = 1010;
const int INF = 0x3fffffff;
int t, n, x, y, maxh;
struct Platfrom {
int left;
int right;
int h;
}platform[MAXN];
int LeftMinTime[MAXN];
int RightMinTime[MAXN];
bool cmp(Platfrom a, Platfrom b) {
if (a.h != b.h)
return a.h > b.h;
else if (a.left != b.left)
return a.left > b.left;
else
return a.right < b.right;
}
int MinTime(int L, bool bLeft) {
int y = platform[L].h;
int x;
if (bLeft)
x = platform[L].left;
else
x = platform[L].right;
int i;
for (i = L + 1; i <= n; i++) {
if (platform[i].left <= x && platform[i].right >= x)
break;
}
if (i <= n) {
if (y - platform[i].h > maxh)
return INF;
}
else {
if (y > maxh)
return INF;
else
return y;
}
int nLeftTime = y - platform[i].h + x - platform[i].left;
int nRightTime = y - platform[i].h + platform[i].right - x;
if (LeftMinTime[i] == -1)
LeftMinTime[i] = MinTime(i, true);
if (RightMinTime[i] == -1)
RightMinTime[i] = MinTime(i, false);
nLeftTime += LeftMinTime[i];
nRightTime += RightMinTime[i];
return min(nRightTime, nLeftTime);
}
int main() {
scanf("%d", &t);
for (int i = 0; i < t; i++) {
memset(LeftMinTime, -1, sizeof(LeftMinTime));
memset(RightMinTime, -1, sizeof(RightMinTime));
scanf("%d %d %d %d", &n, &x, &y, &maxh);
platform[0].left = x;
platform[0].right = x;
platform[0].h = y;
for (int j = 1; j <= n; j++)
scanf("%d %d %d", &platform[j].left, &platform[j].right, &platform[j].h);
sort(platform, platform + n + 1, cmp);
printf("%d\n", MinTime(0, true));
}
return 0;
}
10.5 陪审团的人选
太难了……
#include <cstdio>
#include <stdlib.h>
#include <memory.h>
#include <algorithm>
using namespace std;
int f[30][1000];//f[j][k]表示取j个候选人,使其辩控差为k的所有方案中,辩控和最大的那个方案的辩控和
int Path[30][1000];//Path数组用来记录选了哪些人,方案f(j,k)中最后选的那个候选人编号,记录在Path[j][k]中
int P[300];//控房打分
int D[300];//辩方打分
int ans[300];//存放最终方案的人选
int main() {
int i, j, k;
int t1, t2;
int n, m;
int nMinP_D;//辩控双方总分一样时的辩控差
int nCasesNo = 0;
scanf("%d %d", &n, &m);
while (n + m) {
nCasesNo++;
for (i = 1; i <= n; i++)
scanf("%d %d", &P[i], &D[i]);
memset(f, -1, sizeof(f));
memset(Path, 0, sizeof(Path));
nMinP_D = m * 20;//题目中的辩控差为0,对应到程序中的辩控差就是m*20
f[0][nMinP_D] = 0;//选0个人使得辩控差为nMinP_D的方案,其辩控和就是0
for (j = 0; j < m; j++) {//每次循环选出第j个人,总共要选出m个人
for (k = 0; k <= nMinP_D * 2; k++) {//可能的辩控差的范围是[0,nMinP_D*2]
if (f[j][k] >= 0) {//如果方案可行
for (i = 1; i <= n; i++) {//在方案f(j,k)的基础上,挑下一个人逐个试
if (f[j][k] + P[i] + D[i] > f[j + 1][k + P[i] - D[i]]) {
t1 = j; t2 = k;
while (t1 > 0 && Path[t1][t2] != i) {
t2 -= P[Path[t1][t2]] - D[Path[t1][t2]];
t1--;
}
if (t1 == 0) {
f[j + 1][k + P[i] - D[i]] = f[j][k] + P[i] + D[i];
Path[j + 1][k + P[i] - D[i]] = i;
}
}
}
}
}
}
i = nMinP_D;
j = 0;
while (f[m][i+j] < 0 && f[m][i - j] < 0)
j++;
if (f[m][i + j] > f[m][i - j])
k = i + j;
else
k = i - j;
printf("Jury #%d\n", nCasesNo);
printf("Best jury has value %d for prosecution and value %d for defence:\n", (k - nMinP_D + f[m][k]) / 2, (f[m][k] - k + nMinP_D) / 2);
for (i = 1; i <= m; i++) {
ans[i] = Path[m - i + 1][k];
k -= P[ans[i]] - D[ans[i]];
}
sort(ans + 1, ans + 1 + m);
for (int i = 1; i <= m; i++)
printf(" %d", ans[i]);
printf("\n\n");
scanf("%d %d", &n, &m);
}
return 0;
}