数据结构经典例题解析
请输出longlong情况下最大的有效斐波那契数
问题 A: longlong下最大的有效斐波那契数
#include <stdio.h>
#include <string.h>
int main()
{
long long f[1000];
f[1] = f[2] = 1;
for (int i = 3; i < 1000; ++i) {
f[i] = f[i - 1] + f[i - 2];
if (f[i] < 0) {
printf("%lld\n", f[i - 1]);
break;
}
}
return 0;
}
##### 问题 B: 只要小数部分
超级简单
#include <stdio.h>
#include <string.h>
int main()
{
int a, b;
while (~scanf("%d.%d", &a, &b)) {
printf("%d\n", b);
}
return 0;
}
字符串版本:
#include <stdio.h>
#include <string.h>
int main()
{
char a[100], b[100];
int c = 0;
while (~scanf("%s", a)) {
int t = 0, i = 0, j = 0, flag = 0, n, te = 0, d = 0;
n = strlen(a);
for (i = 0; i < n; i++) {
if (a[i] == '.') {
t = i + 1;
}
}
flag = 1;
for (i = t; i < n; i++) {
if (a[i] != '0') {
d = i;
flag = 0;
break;
}
}
if (flag) {
printf("0\n");
} else {
for (j = d; j < n; j++) {
printf("%c", a[j]);
}
puts("");
}
}
return 0;
}
小颖和小静是一对小姐妹,所以她们喜欢所有事都成双成对
深受老师宠爱的小颖从老师那里拿来了一块画板,画板上刻着很多数字。
小颖和小静看到画板上的偶数,希望能够将画板上存在的偶数凑对,凑对的偶数相加等于她们最喜欢的数字L,但是画板上的数字有很多,而且会出现重复的数字,她们希望你能编写一个程序来计算画板上的偶数能够凑出多少对她们喜欢的数字。
问题 C: 孪生小姐妹
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int num[10007];
int main()
{
int n, l;
while (~scanf("%d %d", &n, &l)) {
memset(num, 0, sizeof num);
int temp;
for (int i = 0; i < n; ++i) {
scanf("%d", &temp);
num[temp]++;
}
// for (int i = 0; i < 10; ++i) cout << num[i] << " ";
if (l & 1) {
printf("what a pity!!!\n");
continue;
}
int sum = 0;
for (int i = 0; i <= 10000; i += 2) {
if (i <= l) {
if (num[i] && num[l - i] ) {
if (i != l - i) {
while (num[i] && num[l - i]) {
num[i]--, num[l - i]--, sum++;
}
}else {
while (num[i] > 2) {
num[i] -= 2;
sum++;
}
}
}
}else break;
}
if (sum == 0) printf("what a pity!!!\n");
else printf("%d\n", sum);
}
return 0;
}
边总有一把青轴键盘,每天在宿舍咔哒咔哒敲代码。因为青轴太带感了,他敲代码甚至不需要打开显示器,就算这样他的代码也常常可以一发 AC。可是有一天边总的键盘被他敲坏了,Home 键和 End 键常常会被自动按下,而他都不知道。
Home 键的功能是将输入光标移动到输入行的最前端,用 ‘H’ 表示,End 键的功能是将输入光标移动到输入行的最末端,用 ‘E’ 表示。
请你在边总打开显示器之前,计算出他输入的字符串在屏幕上会显示的样子。
问题 D: 边总的 Cherry 青轴
链表版代码:
个人觉得链表比较难
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
typedef struct Linklist {
char x;
struct Linklist* next;
}Linklist, * pLinklist;
char ch[100007];
int main()
{
while (~scanf("%s", ch)) {
pLinklist head, temp = NULL, end, now;
head = (pLinklist)malloc(sizeof(Linklist));
end = head;
temp = (pLinklist)malloc(sizeof(Linklist));
int i = 0;
int ls = strlen(ch);
for (; i < ls; ++i) {
temp = (pLinklist)malloc(sizeof(Linklist));
temp->x = ch[i];
if (temp->x == 'E') continue;
if (temp->x == 'H') {
H: now = head;
for (; i < ls; ++i) {
if (ch[i] == 'H') {
++i; goto H;
}
if (ch[i] == 'E') break;
temp = (pLinklist)malloc(sizeof(Linklist));
temp->x = ch[i];
temp->next = now->next;
now->next = temp;
now = temp;
}
}else {
end->next = temp;
end = temp;
}
}
end->next = NULL;
for (temp = head->next; temp != NULL; temp = temp->next) {
printf("%c", temp->x);
}
for (temp = head; temp->next != NULL; ) {
pLinklist tem = temp;
temp = temp->next;
free(tem);
}
puts("");
free(temp);
}
return 0;
}
数组模拟版本:
数组模拟方便理解
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 1e5 + 7;
char a[maxn];
int nxt[maxn];
int main()
{
while(scanf("%s", a + 1) == 1){
memset(nxt, 0, sizeof nxt);
int now = 0, last = 0;
int len = strlen(a+1);
for(int i = 1; i <= len; i++){
if(a[i] == 'H'){
now = 0;
}
else if(a[i] == 'E'){
now = last;
}
else{
nxt[i] = nxt[now];
nxt[now] = i;
if(now == last) last = i;
now = i;
}
}
for(int i = nxt[0]; i != 0; i = nxt[i]){
printf("%c", a[i]);
}
printf("\n");
}
return 0;
}
刘莎莎大学毕业以后去当了一个船坞管理员,她每天都会接收到很多船进出的请求。这几天她遇到了一个编号为0-9的船队,他们有个奇葩的习惯,就是必须按照他们给出的编号顺序进出船坞,船坞可以停下这十条船,但船坞在前一条船开出船坞前没有别的路可以让后一条船开出,刘莎莎在校没有好好做ACM的题所以没有办法满足船队的要求,老板对她十分不满。你能帮助她避免被开除的命运么?
问题 E: 可怜的船坞管理员
栈就完事了
#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int stack[15];
int top = 0;
int n;
int a[16], b[16];
char ch1[50];
while (~scanf("%d", &n)) {
top = 0;
for (int i = 0; i < n; ++i) {
scanf("%1d", &a[i]);
}
for (int i = 0; i < n; ++i) {
scanf("%1d", &b[i]);
}
stack[0] = -10;
stack[++top] = a[0];
ch1[0] = 'i';
int k = 1;
int t = 0;
for (int i = 1; i < n;) {
if (stack[top] == b[t]) {
t++;
top--;
ch1[k++] = 'o';
}else {
stack[++top] = a[i];
ch1[k++] = 'i';
i++;
}
}
if (top > 0) {
while (stack[top] == b[t]) {
--top, ++t;
ch1[k++] = 'o';
}
}
if (top > 0) {
printf("No.\n");
printf("Finish\n");
}else {
printf("Yes.\n");
for (int i = 0; i < k; ++i) {
if (ch1[i] == 'i') printf("In\n");
if (ch1[i] == 'o') printf("Out\n");
}
cout << "Finish" << endl;
}
}
return 0;
}
- for循环的开头 f ,后带一个数字n,表示循环次数(0 < n <= 100)
- for循环终止语句e,表示循环终止,每一个f 对应一个 n
- 自增指令,+,遇到使其加1
初始 x 为0
问题 F: 计算姬的烦恼
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
#include <queue>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
using namespace std;
typedef long long ll;
string a[120000];
int num[120000];
stack<ll> s;
int main()
{
// map <string, int> mp;
//
// mp["+"] = 0;
// mp["f"] = 1;
// mp["e"] = 2;
int n;
ll k = 1LL * 10000000;
scanf("%d", &n);
memset(num, 0, sizeof num);
for (int i = 0; i < n; ++i) {
cin >> a[i];
if (a[i][0] == 'f') cin >> num[i];
// cout << a[i] << " " << num[i] << endl;
}
ll x = 0;
ll tem = 1;
// bool flag = false;
bool flag_x = false;
// cout << n << endl;
for (int i = 0; i < n; ++i) {
if (a[i][0] == '+' ) {
if (s.empty()) x += 1;
else x += s.top();
}
// cout << n << endl;
if (a[i][0] == 'f') {
if (s.empty()) tem = 1;
else tem = s.top();
tem *= num[i];
if (tem > k) s.push(k + 1);
else s.push(tem);
}
// cout << n << endl;
if (a[i][0] == 'e') {
s.pop();
}
if (x > k) {
flag_x = true;
break;
}
// printf("%I64d %I64d %d\n", x, tem, top);
}
// std::cout << "1" << '\n';
if (flag_x) printf("Go Out!!!\n");
else printf("%lld\n", 1LL * x);
return 0;
}
鱼鱼是开心消消乐的忠实粉丝,奈何鱼鱼智商爆表,觉得开心消消乐过于简单,于是便自创了独门消消乐,独乐乐不如众乐乐,于是他想和你一起玩这个游戏。这个游戏的规则如下:假设你有一个长度为N的数字序列,序列的每个位置上都有一个数字,你可以任意选取两个相同并且相邻的数字消掉,每次消掉两个数字就会获得1分。由于数字在序列中具有一个相对位置,所有当消掉数字时,便会出现空位,后面的数字就会向前移动,补齐空位。作为一名资深的玩家,你想获得尽可能高的分数。
问题 G: 开心消消乐
#include <stdio.h>
int stack[100007];
int main()
{
int top = 0;
int n;
while (~scanf("%d", &n)) {
top = 0;
int temp;
int sum = 0;
for (int i = 0; i < n; ++i) {
scanf("%d", &temp);
if (!top) {
stack[++top] = temp;
}else {
if (temp == stack[top]) {
top--;
sum++;
}else {
stack[++top] = temp;
}
}
}
printf("%d\n", sum);
}
return 0;
}
Ay12 + By22 + Cy32 + Dy42 = 0。
问题H:零的忧伤
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <memory.h>
using namespace std;
int f1[1000005]; //保存得数是正的
int f2[1000005]; //保存得数是负的
int main()
{
int i, j, k, sum;
int a, b, c, d;
while (scanf("%d %d %d %d", &a, &b, &c, &d) != EOF) {
//abcd全部大于0或者小于0,肯定无解。要加上这个,不然超时
if (a > 0 && b > 0 && c > 0 && d > 0 || a < 0 && b < 0 && c < 0 && d < 0) {
printf("0\n");
continue;
}
memset(f1, 0, sizeof(f1));
memset(f2, 0, sizeof(f2));
for (i = 1; i <= 100; i++) {
for (j = 1; j <= 100; j++) {
k = a * i * i + b * j * j;
if (k >= 0) f1[k]++; //k>=0 f1[k]++
else f2[-k]++; //k<0 f2[k]++
}
}
sum = 0;
for (i = 1; i <= 100; i++) {
for (j = 1; j <= 100; j++) {
k = c * i * i + d * j * j;
if (k > 0) sum += f2[k]; //若k为正,加上的f2[k]
else sum += f1[-k]; //若k为负,加上的f1[k]
}
}
printf("%d\n", 16 * sum); //每个解有正有负,结果有2^4种
}
return 0;
}
二维数组
问题 I: 美丽校园——绿化I
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int map[1005][1005];
int main(int argc, char const *argv[])
{
int n, m, k;
while (~scanf("%d %d %d", &n, &m, &k) ) {
if (!n && !m && !k) break;
memset(map, 0, sizeof(map));
int a, b, c, d;
for (int i = 0; i < k; ++i) {
scanf("%d %d %d %d", &a, &b, &c, &d);
for (int j = a; j <= c; ++j) {
for (int s = b; s <= d; ++s) {
map[j][s] = 1;
}
}
}
int sum = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (map[i][j]) sum++;
}
}
cout << sum << endl;
}
return 0;
}
三维数组
问题 J: 美丽校园——绿化II
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int map[55][55][55];
int main(int argc, char const *argv[])
{
int n, m, k, l;
while (~scanf("%d %d %d %d", &n, &m, &l, &k) ) {
if (!n && !m && !k && !l) break;
memset(map, 0, sizeof(map));
int a, b, c, d, e, f;
for (int i = 0; i < k; ++i) {
cin >> a >> b >> c >> d >> e >> f;
for (int j = a; j <= d; ++j) {
for (int s = b; s <= e; ++s) {
for (int t = c; t <= f; ++t)
map[j][s][t] = 1;
}
}
}
int sum = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
for (int t = 1; t <= l; ++t)
if (map[i][j][t]) sum++;
}
}
cout << sum << endl;
}
return 0;
}
: 15059900716 -> 029900716
问题 K: 办理手机短号业务送话费
#include <cstdio>
#include <cstring>
int main()
{
char num[20];
while (~scanf("%s", num)) {
printf("029");
for (int i = 5; i < 11; ++i) {
printf("%c", num[i]);
}
printf("\n"); //记得换行
}
return 0;
}