PKU《程序设计导引及在线实践》刷题记录(上)

2.1 鸡兔同笼

#include <cstdio>

int main() {
	int n;
	scanf("%d", &n);
	while (n--) {
		int total;
		int chi, rab;
		scanf("%d", &total);
		if (total % 2 != 0) {
			printf("0 0\n");
			continue;
		}
		else
			printf("%d %d\n", total / 4 + (total - total / 4 * 4) / 2, total / 2);
	}
	return 0;
}

2.2棋盘上的距离

#include <cstdio>
#include <cmath>

int main() {
	int ncases;
	scanf("%d", &ncases);
	while (ncases--) {
		int dx, dy;
		char x[5], y[5];
		scanf("%s %s", x, y);
		dx = abs(y[0] - x[0]);
		dy = abs(y[1] - x[1]);
		//王
		printf("%d ", dx > dy ? dx : dy);
		//后
		if (dx == 0 || dy == 0 || dx == dy)
			printf("1 ");
		else
			printf("2 ");
		//车
		if (dx == 0 || dy == 0)
			printf("1 ");
		else
			printf("2 ");
		//象
		if (dx != dy)
			printf("Inf\n");
		else
			printf("1\n");
	}
	return 0;
}

2.3 校门外的树

#include <cstdio>
#include <algorithm>
using namespace std;

int tree[10010];

int main() {
	int L, M;
	scanf("%d %d", &L, &M);
	fill(tree, tree + L + 1, 1);
	for (int i = 0; i < M; i++) {
		int begin, end;
		scanf("%d %d", &begin, &end);
		fill(tree + begin, tree + end + 1, 0);
	}
	int ans = 0;
	for (int i = 0; i <= L; i++)
		ans += tree[i];
	printf("%d", ans);
	return 0;
}

2.4填词

#include <cstdio>

int main() {
	char c;
	int num[30] = { 0 };
	int M, N, P;
	scanf("%d %d %d", &M, &N, &P);
	getchar();
	for (int i = 0; i < M; i++) {
		for (int j = 0; j < N; j++) {
			scanf("%c", &c);
			num[c - 'A']++;
		}
		getchar();
	}
	for (int i = 0; i < P; i++) {
		char temp[500];
		scanf("%s", temp);
		for (int j = 0; temp[j] != '\0'; j++)
			num[temp[j] - 'A']--;
	}
	for (int i = 0; i < 26; i++) {
		while (num[i] != 0) {
			printf("%c", i + 'A');
			num[i]--;
		}
	}
	return 0;
}

2.5装箱问题
太菜了,没想到这题居然还是不会,没学好啊

#include <cstdio>

int main() {
	while (1) {
		int ans = 0;
		int a, b, c, d, e, f;//用来存放订单数
		int x, y;//x表示剩下2*2的空间的数量,y表示剩下1*1的空间的数量
		scanf("%d %d %d %d %d %d", &a, &b, &c, &d, &e, &f);
		if (a == 0 && b == 0 && c == 0 && d == 0 && e == 0 && f == 0)
			break;
		int left[4] = { 0,5,3,1 };
		ans = f + e + d + (c + 3) / 4;
		x = 5 * d + left[c % 4];
		if (b > x)
			ans += (b - x + 8) / 9;
		x = 36 * ans - 36 * f - 25 * e - 16 * d - 9 * c - 4 * b;
		if (a > x)
			ans += (a - x + 35) / 36;
		printf("%d\n", ans);
	}
	return 0;
}

3.1确定进制
太菜了!!怎么感觉自己还不如第一遍刷题的自己??居然忘了进制转换的时候,如果有个要被转换的数比product大,应当退出!!

#include <cstdio>

int Change(char p[], int product) {
	int ans = 0;
	for (int i = 0; p[i] != '\0'; i++) {
		if (p[i] - '0' >= product)
			return -1;
		ans = ans * product + p[i] - '0';
	}
	return ans;
}

int main() {
	char p[10], q[10], r[10];
	scanf("%s %s %s", p, q, r);
	for (int i = 2; i <= 16; i++) {
		int a = Change(p, i);
		int b = Change(q, i);
		int c = Change(r, i);
		if (a*b == c) {
			printf("%d", i);
			return 0;
		}
	}
	printf("0");
	return 0;
}

3.2相邻数字的基数不等比:skew数

#include <cstdio>
#include <cstring>

int main() {
	int base[32];
	base[0] = 1;
	for (int i = 1; i < 32; i++)
		base[i] = 2 * base[i - 1] + 1;
	while (1) {
		char p[40];
		scanf("%s", p);
		if (p[0] == '0')
			break;
		long long ans = 0;
		int len = strlen(p);
		for (int i = len - 1; i >= 0; i--) {
			ans += (p[i] - '0')*base[len - i - 1];
		}
		printf("%ld\n", ans);
	}
	return 0;
}

4.2统计字符数

#include <cstdio>
#include <cstring>

int main() {
	int n;
	scanf("%d", &n);
	while (n--) {
		char str[1010];
		scanf("%s", str);
		int num[30] = { 0 };
		int MAXID = 0;
		for (int i = 0; str[i] != '\0'; i++) 
			num[str[i] - 'a']++;
		for (int i = 1; i < 26; i++) {
			if (num[i] > num[MAXID])
				MAXID = i;
		}
		printf("%c %d\n", 'a' + MAXID, num[MAXID]);
	}
	return 0;
}

4.3 487-3279

#include <iostream>
#include <algorithm>
#include <map>
#include <string>
using namespace std;

int main() {
	map<string, int> mp;
	int n;
	scanf("%d", &n);
	while (n--) {
		string s;
		cin >> s;
		string temp;
		//输入字符串并进行映射
		for (int i = 0; s[i] != '\0'; i++) {
			if (s[i] == 'A' || s[i] == 'B' || s[i] == 'C') {
				temp += "2";
			}
			if (s[i] == 'D' || s[i] == 'E' || s[i] == 'F') {
				temp += "3";
			}
			if (s[i] == 'G' || s[i] == 'H' || s[i] == 'I') {
				temp += "4";
			}
			if (s[i] == 'J' || s[i] == 'K' || s[i] == 'L') {
				temp += "5";
			}
			if (s[i] == 'M' || s[i] == 'N' || s[i] == 'O') {
				temp += "6";
			}
			if (s[i] == 'P' || s[i] == 'R' || s[i] == 'S') {
				temp += "7";
			}
			if (s[i] == 'T' || s[i] == 'U' || s[i] == 'V') {
				temp += "8";
			}
			if (s[i] == 'W' || s[i] == 'X' || s[i] == 'Y') {
				temp += "9";
			}
			if (s[i] >= '0'&&s[i] <= '9')
				temp += s[i];
		}
		temp.insert(temp.begin() + 3, '-');
		if (mp.count(temp) != 0)
			mp[temp]++;
		else
			mp[temp] = 1;
	}
	bool flag = false;
	for (map<string, int>::iterator it = mp.begin(); it != mp.end(); it++) {
		if (it->second > 1) {
			cout << it->first << " " << it->second << endl;
			flag = true;
		}
	}
	if (flag == false)
		cout << "No duplicates.";
	return 0;
}

4.4子串

#include <iostream>
#include <string>
using namespace std;

int main() {
	int n;
	scanf("%d", &n);
	while (n--) {
		int t;
		cin >> t;
		string str[110];
		string min;
		cin >> str[0];
		min = str[0];
		for (int i = 1; i < t; i++) {
			cin >> str[i];
			if (str[i].length() < min.length())
				min = str[i];
		}
		int minlen = min.length();
		int i;
		bool flag = false;
		for (i = minlen; i > 0; i--) {//子串长度从最长开始逐次递减
			for (int j = 0; j + i <= minlen; j++) {//子串起始位置枚举
				string temp;
				temp.insert(temp.begin(), min.begin() + j, min.begin() + i + j);
				flag = true;
				for (int k = 0; k < t; k++) {
					if (str[k] == min)
						continue;
					string rev;
					for (int s = str[k].length() - 1; s >= 0; s--)
						rev += str[k][s];
					if (str[k].find(temp) == string::npos&&rev.find(temp) == string::npos) {
						flag = false;
					}
				}
				if (flag == true)
					break;
			}
			if (flag == true) {
				printf("%d\n", i);
				break;
			}
		}
		if (flag == false)
			printf("0\n");
	}
	return 0;
}

4.5最难的问题

#include <iostream>
#include <string>
using namespace std;

int main() {
	while (1) {
		string start, end, sent;
		getline(cin, start);
		if (start == "ENDOFINPUT")
			break;
		getline(cin, sent);
		getline(cin, end);
		string ans;
		for (int i = 0; sent[i] != '\0'; i++) {
			if (sent[i] >= 'A'&&sent[i] <= 'Z')
				ans += (sent[i]-'A' + 26 - 5) % 26 + 'A';
			else
				ans += sent[i];
		}
		cout << ans << endl;
	}
	return 0;
}

5.1判断闰年

#include <cstdio>

int main() {
	int year;
	scanf("%d", &year);
	if (year % 4 != 0)
		printf("N");
	else {
		if (year % 3200 == 0) {
			printf("N");
			return 0;
		}
		if (year % 100 == 0)
			if (year % 400 != 0) {
				printf("N");
				return 0;
			}
		printf("Y");
	}
	return 0;
}

5.2细菌繁殖

#include <cstdio>

int main() {
	int month[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	int n;
	scanf("%d", &n);
	while (n--) {
		int Mst, Dst, Men, Den;
		long long num;
		scanf("%d %d %lld %d %d", &Mst, &Dst, &num, &Men, &Den);
		int lag = 0;
		while (Mst != Men || Dst != Den) {
			lag++;
			if (Dst == month[Mst]) {
				Dst = 1;
				Mst++;
			}
			else
				Dst++;
		}
		for (int i = 0; i < lag; i++)
			num += num;
		printf("%lld\n", num);
	}
	return 0;
}

5.3 日历问题

#include <cstdio>
int month[2][13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31,0,31,29,31,30,31,30,31,31,30,31,30,31 };
char week[7][10] = { "Saturday","Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };
int year[2] = { 365,366 };

bool IsRun(int year) {
	if (year % 4 != 0)
		return false;
	if (year % 100 == 0 && year % 400 != 0)
		return false;
	return true;
}

int main() {
	while (1) {
		int lag;
		scanf("%d", &lag);
		if (lag == -1)
			break;
		int temp = 0;
		int Y = 2000, M = 1, D = 1;
		while (temp != lag) {
			bool flag = IsRun(Y);
			if (lag - temp > year[flag]) {
				temp += year[flag];
				Y++;
			}
			else {
				temp++;
				if (D == month[flag][M]) {
					D = 1;
					M++;
					if (M == 13) {
						M = 1;
						Y++;
					}
				}
				else
					D++;
			}
		}
		printf("%04d-%02d-%02d %s\n", Y, M, D, week[lag % 7]);
	}
	return 0;
}

5.4玛雅历
这题一开始就不会做=-=,现在看到这个题还是犯怵。。。太菜了

#include <cstdio>
#include <cstring>

char maya[19][10] = { "pop","no","zip","zotz","tzec","xul","yoxkin","mol",
					"chen","yax","zac","ceh","mac","kankin","muan","pax",
					"koyab","cumhu","uayet"};
char holly[20][10] = { "imix","ik","akbal","kan","chicchan","cimi","manik",
					"lamat","muluk","ok","chuen","eb","ben","ix","mem","cib",
					"caban","eznab","canac","ahau" };

int main() {
	int n;
	scanf("%d", &n);
	printf("%d\n", n);
	while (n--) {
		int day, year;
		char mon[10];
		int sum = 0;
		scanf("%d. %s %d", &day, mon, &year);
		sum += year * 365;
		for (int i = 0; i < 19; i++) {
			if (strcmp(maya[i], mon) == 0) {
				sum += i * 20;
				break;
			}
		}
		sum += day;
		printf("%d %s %d\n", sum % 13 + 1, holly[sum % 20], sum / 260);
	}
	return 0;
}

5.5 时区间时间的转换

#include <cstdio>
#include <string.h>

int difference(char zone1[], char zone2[]) {
	char zone[32][7] = {
		"UTC","GMT","BST","IST","WET","WEST","CET","CEST",
		"EET","EEST","MSK","MSD","AST","ADT","NST","NDT",
		"EST","EDT","CST","CDT","MST","MDT","PST","PDT",
		"HST","AKST","AKDT","AEST","AEDT","ACST","ACDT","AWST" };
	double time[32] = { 0,0,1,1,0,1,1,2,2,3,3,4,-4,-3,-3.5,-2.5,-5,-4,-6,
		-5,-7,-6,-8,-7,-10,-9,-8,10,11,9.5,10.5,8 };
	int i, j;
	for (i = 0; strcmp(zone[i], zone1) != 0; i++);
	for (j = 0; strcmp(zone[j], zone2) != 0; j++);
	return (int)((time[i] - time[j]) * 60);
}

int main() {
	int n;
	scanf("%d", &n);
	while (n--) {
		char time[9];
		int hours, minutes;
		scanf("%s", time);
		switch (time[0]) {
		case'n':
			hours = 12;
			minutes = 0;
			break;
		case'm':
			hours = 0;
			minutes = 0;
			break;
		default:
			sscanf(time, "%d:%d", &hours, &minutes);
			hours %= 12;
			scanf("%s", time);
			if (time[0] == 'p')
				hours += 12;
		}
		char timezone1[7], timezone2[7];
		scanf("%s %s", timezone1, timezone2);
		int newtime;
		newtime = hours * 60 + minutes + difference(timezone2, timezone1);
		if (newtime < 0)
			newtime += 1440;
		newtime %= 1440;
		switch (newtime) {
		case 0:
			printf("midnight\n"); break;
		case 720:
			printf("noon\n"); break;
		default:
			hours = newtime / 60;
			minutes = newtime % 60;
			if (hours == 0)
				printf("12:%02d a.m.\n", minutes);
			else if (hours < 12)
				printf("%d:%02d a.m.\n", hours, minutes);
			else if (hours == 12)
				printf("12:%02d p.m.\n", minutes);
			else if (hours > 12)
				printf("%d:%02d p.m.\n", hours % 12, minutes);
		}
	}
	return 0;
}

6.1 约瑟夫问题

#include <cstdio>

typedef struct Monkey {
	int data;
	struct Monkey *next;
}monkey, *linklist;

int main() {
	while (1) {
		linklist Head;
		Head = new Monkey;
		Head->next = NULL;
		linklist Tail;
		Tail = Head;
		int num, k;
		scanf("%d %d", &num, &k);
		if (num == 0 && k == 0)
			break;
		if (k == 1)
			printf("%d\n", num);
		else {
			for (int i = 1; i <= num; i++) {
				linklist temp;
				temp = new Monkey;
				temp->data = i;
				temp->next = NULL;
				Tail->next = temp;
				Tail = temp;
			}
			Tail->next = Head->next;
			delete Head;
			linklist L = Tail->next;
			while (L->next != L) {
				for (int i = 1; i < k - 1; i++)
					L = L->next;
				linklist temp = L->next;
				L->next = temp->next;
				delete temp;
				L = L->next;
			}
			printf("%d\n", L->data);
		}
	}
	return 0;
}

6.2 花生问题
很奇怪,OJ仿佛识别不了math.h里的abs?

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

int Field[55][55];

int main() {
	int T;
	scanf("%d", &T);
	while (T--) {
		int M, N, K;
		scanf("%d %d %d", &M, &N, &K);
		for (int i = 1; i <= M; i++)
			for (int j = 1; j <= N; j++)
				scanf("%d", &Field[i][j]);
		int Time = 0;
		int Sum = 0;
		int curi = 0, curj = 0;
		while (Time <= K) {
			//首先找到最大的
			int maxn = 0;
			int maxi = 0, maxj = 0;
			for (int i = 1; i <= M; i++)
				for (int j = 1; j <= N; j++) {
					if (Field[i][j] > maxn) {
						maxn = Field[i][j];
						maxi = i;
						maxj = j;
					}
				}
			if (maxn == 0)
				break;
			if (curi == 0)
				curj = maxj;
			if (Time + maxi + 1 + abs(maxi - curi) + abs(maxj - curj) <= K) {
				Time += 1 + abs(maxi - curi) + abs(maxj - curj);
				curi = maxi;
				curj = maxj;
				Sum += Field[maxi][maxj];
				Field[maxi][maxj] = 0;
			}
			else
				break;
		}
		printf("%d\n", Sum);
	}
	return 0;
}

6.3显示器
主要方法:用char字符数组存每个位置都被哪个数字占了

#include <cstdio>
#include <string.h>
char n1[11] = { "- -- -----" };
char n2[11] = { "|   ||| ||" };
char n3[11] = { "|||||  |||" };
char n4[11] = { "  ----- --" };
char n5[11] = { "| |   | | " };
char n6[11] = { "|| |||||||" };
char n7[11] = { "- -- -- --" };
int main() {
	while (1) {
		int s;
		char szNumber[20];
		int nDigit, nLength, i, j, k;
		scanf("%d %s", &s, szNumber);
		if (s == 0)
			break;
		nLength = strlen(szNumber);
		for (int i = 0; i < nLength; i++) {
			nDigit = szNumber[i] - '0';
			printf(" ");
			for (j = 0; j < s; j++)
				printf("%c", n1[nDigit]);
			printf(" ");
			printf(" ");//这个是数字间的空格
		}
		printf("\n");

		for (i = 0; i < s; i++) {
			for (j = 0; j < nLength; j++) {
				nDigit = szNumber[j] - '0';
				printf("%c", n2[nDigit]);
				for (k = 0; k < s; k++)
					printf(" ");
				printf("%c", n3[nDigit]);
				printf(" ");
			}
			printf("\n");
		}

		for (int i = 0; i < nLength; i++) {
			nDigit = szNumber[i] - '0';
			printf(" ");
			for (j = 0; j < s; j++)
				printf("%c", n4[nDigit]);
			printf(" ");
			printf(" ");
		}
		printf("\n");

		for (i = 0; i < s; i++) {
			for (j = 0; j < nLength; j++) {
				nDigit = szNumber[j] - '0';
				printf("%c", n5[nDigit]);
				for (k = 0; k < s; k++)
					printf(" ");
				printf("%c", n6[nDigit]);
				printf(" ");
			}
			printf("\n");
		}

		for (int i = 0; i < nLength; i++) {
			nDigit = szNumber[i] - '0';
			printf(" ");
			for (j = 0; j < s; j++)
				printf("%c", n7[nDigit]);
			printf(" ");
			printf(" ");
		}
		printf("\n");
		printf("\n");
	}
	return 0;
}

6.4 排列
STL大法好

#include <cstdio>
#include <algorithm>
using namespace std;

int main() {
	int n;
	scanf("%d", &n);
	while (n--) {
		int a[1050];
		int t, k;
		scanf("%d %d", &t, &k);
		for (int i = 0; i < t; i++)
			scanf("%d", &a[i]);
		for (int i = 0; i < k; i++)
			next_permutation(a, a + t);
		for (int i = 0; i < t; i++)
			printf("%d ", a[i]);
		printf("\n");
	}
	return 0;
}

7.1 大整数加法
我是猪……为啥做题做的还不如第一次做的好??忽略了0+0的问题,WA好几次

#include <cstdio>
#include <string.h>

int main() {
	char a[210], b[210];
	int ai[210] = { 0 }, bi[210] = { 0 };
	int ans[210] = { 0 };
	scanf("%s", a);
	scanf("%s", b);
	int alen = strlen(a), blen = strlen(b);
	for (int i = alen - 1, j = 0; i >= 0; i--, j++)
		ai[j] = a[i] - '0';
	for (int i = blen - 1, j = 0; i >= 0; i--, j++)
		bi[j] = b[i] - '0';
	int max = alen > blen ? alen : blen;
	int carry = 0;
	for (int i = 0; i < max; i++) {
		ans[i] = (ai[i] + bi[i] + carry) % 10;
		carry= (ai[i] + bi[i] + carry) / 10;
	}
	if (carry != 0)
		ans[max] = carry;
	while (ans[max] == 0)
		max--;
	if (max < 0)
		printf("0");
	else {
		for (int i = max; i >= 0; i--)
			printf("%d", ans[i]);
	}
	return 0;
}

7.2 大整数乘法

#include <cstdio>
#include <string.h>

int main() {
	char a[210], b[210];
	int ai[210] = { 0 }, bi[210] = { 0 };
	int ans[450] = { 0 };
	scanf("%s", a);
	scanf("%s", b);
	int alen = strlen(a), blen = strlen(b);
	for (int i = alen - 1, j = 0; i >= 0; i--, j++)
		ai[j] = a[i] - '0';
	for (int i = blen - 1, j = 0; i >= 0; i--, j++)
		bi[j] = b[i] - '0';
	for (int i = 0; i < alen; i++)
		for (int j = 0; j < blen; j++)
			ans[i + j] += ai[i] * bi[j];
	for (int i = 0; i < alen + blen; i++) {
		if (ans[i] >= 10) {
			ans[i + 1] += ans[i] / 10;
			ans[i] %= 10;
		}
	}
	int max = alen + blen;
	while (ans[max] == 0)
		max--;
	if (max < 0)
		printf("0");
	else {
		for (int i = max; i >= 0; i--)
			printf("%d", ans[i]);
	}
	return 0;
}

7.3 大整数除法
我放弃,这题真要是考场上出来我可能会自杀
贴上书里给的代码

#include <cstdio>
#include <string.h>
const int MAXL = 200;
char szLine1[MAXL + 10];
char szLine2[MAXL + 10];
int an1[MAXL + 10];//被除数,an1[0]对应于个位
int an2[MAXL + 10];//除数,an2[0]对应于个位
int Result[MAXL + 10];//存放商,Result[0]对应于个位

int Substract(int *p1, int *p2, int nLen1, int nLen2) {
	//判断p1是否比p2大,如果不是,返回-1
	if (nLen1 < nLen2)
		return -1;
	bool bLarger = false;
	if (nLen1 == nLen2) {
		for (int i = nLen1 - 1; i >= 0; i--) {
			if (p1[i] > p2[i])
				bLarger = true;
			else if (p1[i] < p2[i]) {
				if (!bLarger)
					return -1;
			}
		}
	}
	for (int i = 0; i < nLen1; i++) {
		p1[i] -= p2[i];
		if (p1[i] < 0) {
			p1[i] += 10;
			p1[i + 1]--;
		}
	}
	for (int i = nLen1 - 1; i >= 0; i--)
		if (p1[i])
			return i + 1;
	return 0;
}

int main() {
	char szBlank[20];
	scanf("%s", szLine1);
	scanf("%s", szLine2);
	int nLen1 = strlen(szLine1);
	memset(an1, 0, sizeof(an1));
	memset(an2, 0, sizeof(an2));
	memset(Result, 0, sizeof(Result));
	for (int i = nLen1 - 1, j = 0; i >= 0; i--)
		an1[j++] = szLine1[i] - '0';
	int nLen2 = strlen(szLine2);
	for (int i = nLen2 - 1, j = 0; i >= 0; i--)
		an2[j++] = szLine2[i] - '0';
	if (nLen1 < nLen2) {
		printf("0");
		return 0;
	}
	nLen1 = Substract(an1, an2, nLen1, nLen2);
	if (nLen1 < 0) {
		printf("0");
		return 0;
	}
	else if (nLen1 == 0) {
		printf("1");
		return 0;
	}
	Result[0]++;
	int nTimes = nLen1 - nLen2;
	if (nTimes < 0)
		goto OutputResult;
	else if (nTimes > 0) {
		for (int i = nLen1 - 1; i >= 0; i--) {
			if (i >= nTimes)
				an2[i] = an2[i - nTimes];
			else
				an2[i] = 0;
		}
	}
	nLen2 = nLen1;
	for (int j = 0; j <= nTimes; j++) {
		int nTmp;
		//一直减到不够减为止
		//先减去若干个an2*(10的nTimes次方)
		//不够减了,再减去若干个an2*(10的nTimes-1次方)
		while ((nTmp = Substract(an1, an2 + j, nLen1, nLen2 - j)) >= 0) {
			nLen1 = nTmp;
			Result[nTimes - j]++;//每成功减一次,则将商的对应位加1
		}
	}
OutputResult:
	for (int i = 0; i < MAXL; i++) {
		if (Result[i] >= 10) {
			Result[i + 1] += Result[i] / 10;
			Result[i] %= 10;
		}
	}
	bool bStartOutput = false;
	for (int i = MAXL; i >= 0; i--) {
		if (bStartOutput)
			printf("%d", Result[i]);
		else if (Result[i]) {
			printf("%d", Result[i]);
			bStartOutput = true;
		}
	}
	if (!bStartOutput)
		printf("0");
	return 0;
}

7.4 麦森数
我输了,我还是不会做
主要的思想是用到了快速幂

#include <cstdio>
#include <math.h>
#include <memory.h>
#define LEN 125

/*
Multiply函数功能是计算高精度乘法a*b
结果的末500未放在a中
*/
void Multiply(int* a, int* b) {
	int nCarry;//进位
	int nTmp;
	int c[LEN];//存放结果的末500位
	memset(c, 0, sizeof(int)*LEN);
	for (int i = 0; i < LEN; i++) {
		nCarry = 0;
		for (int j = 0; j < LEN - i; j++) {
			nTmp = c[i + j] + a[j] * b[i] + nCarry;
			c[i + j] = nTmp % 10000;
			nCarry = nTmp / 10000;
		}
	}
	memcpy(a, c, LEN * sizeof(int));
}

int main() {
	int p;
	int anPow[LEN];//存放不断增长的2的次幂
	int aResult[LEN];//存放最终结果的末500位
	scanf("%d", &p);
	printf("%d\n", (int)(p*log10(2)) + 1);
	//将2的次幂初始化为2^(2^0)
	//最终结果初始化为1
	anPow[0] = 2;
	aResult[0] = 1;
	for (int i = 1; i < LEN; i++) {
		anPow[i] = 0;
		aResult[i] = 0;
	}
	//计算2的p次方
	while (p > 0) {
		if (p & 1)
			Multiply(aResult, anPow);
		p >>= 1;
		Multiply(anPow, anPow);
	}
	aResult[0]--;//2的p次方算出后减1

	for (int i = LEN - 1; i >= 0; i--) {
		if (i % 25 == 12)
			printf("%02d\n%02d", aResult[i] / 100, aResult[i] % 100);
		else {
			printf("%04d", aResult[i]);
			if (i % 25 == 0)
				printf("\n");
		}
	}
	return 0;
}

8.2 生理周期
想太复杂了。。。以为在给定的day前面也可能会有,然后输出一个负的,结果一直WA……直接从day+1开始判断,AC……

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

int main() {
	int tili, ganqing, zhili;
	scanf("%d %d %d", &tili, &ganqing, &zhili);
	int day;
	scanf("%d", &day);
	for (int i = day+1; i <= 21252+day; i++) {
		if (abs(i - tili) % 23 == 0 && abs(i - ganqing) % 28 == 0 && abs(i - zhili) % 33 == 0) {
			printf("%d", i - day);
			break;
		}
	}
	return 0;
}

8.3 称硬币
写了大半天,WA一百遍,然后发现自己判断硬币的逻辑出了问题。
把书里的正确的代码贴上来,也是复习了。
另,把自己错误的代码放在后面,分析错误所在。

#include <cstdio>
#include <string.h>

char left[3][7], right[3][7], result[3][5];

bool isLight(char x) {
	for (int i = 0; i < 3; i++) {
		switch (result[i][0]) {
		case'u':if (strchr(right[i], x) == NULL)
			return false;
			break;
		case'e':if (strchr(right[i], x) != NULL || strchr(left[i], x) != NULL)
			return false;
			break;
		case'd':
			if (strchr(left[i], x) == NULL)
				return false;
			break;
		}
	}
	return true;
}

bool isHeavy(char x) {
	for (int i = 0; i < 3; i++) {
		switch (result[i][0]) {
		case'u':if (strchr(left[i], x) == NULL)
			return false;
			break;
		case'e':if (strchr(right[i], x) != NULL || strchr(left[i], x) != NULL)
			return false;
			break;
		case'd':
			if (strchr(right[i], x) == NULL)
				return false;
			break;
		}
	}
	return true;
}

int main() {
	int n;
	char c;
	scanf("%d", &n);
	while (n--) {
		for (int i = 0; i < 3; i++)
			scanf("%s %s %s", left[i], right[i], result[i]);
		for (c = 'A'; c <= 'L'; c++) {
			if (isLight(c)) {
				printf("%c is the counterfeit coin and it is light.\n", c);
				break;
			}
			if (isHeavy(c)) {
				printf("%c is the counterfeit coin and it is heavy.\n", c);
				break;
			}
		}
	}
	return 0;
}

错误代码:
错误举例:这种判断方法,假如j是假币,前两次i和j一起称,最后一次只称了j。这样会判断i是假币。

#include <iostream>
#include <string>
using namespace std;

int main() {
	int n;
	scanf("%d", &n);
	while (n--) {
		string left[3], right[3], result[3];
		for (int i = 0; i < 3; i++)
			cin >> left[i] >> right[i] >> result[i];
		for (char temp='A'; temp <= 'L'; temp++) {
			int Isfalse = -1;//0表示更轻,1表示更重,2表示是真币
			bool flag = false;//有没有出现
			for (int j = 0; j < 3; j++) {
				if (Isfalse == 2)
					break;
				if (left[j].find(temp) != string::npos || right[j].find(temp) != string::npos) {
					flag = true;
					if ((left[j].find(temp) != string::npos && result[j][0] == 'e') || (right[j].find(temp) != string::npos  && result[j][0] == 'e'))
						Isfalse = 2;
					if ((left[j].find(temp) != string::npos  && result[j][0] == 'u') || (right[j].find(temp) != string::npos  && result[j][0] == 'd'))
						Isfalse = 1;
					if ((left[j].find(temp) != string::npos  && result[j][0] == 'd') || (right[j].find(temp) != string::npos && result[j][0] == 'u'))
						Isfalse = 0;
				}
			}
			if (flag&&Isfalse != 2) {
				if (Isfalse == 0)
					printf("%c is the counterfeit coin and it is light.\n", temp);
				else if (Isfalse == 1)
					printf("%c is the counterfeit coin and it is heavy.\n", temp);
				break;
			}
		}
	}
	return 0;
}

8.4 完美立方

#include <cstdio>

int main() {
	int N;
	scanf("%d", &N);
	int a, b, c, d;
	for (a = 2; a <= N; a++) {
		for (b = 2; b <= N; b++) {
			for (c = b; c <= N; c++) {
				for (d = c; d <= N; d++) {
					if (a*a*a < b*b*b + c * c*c + d * d*d)
						break;
					if (a*a*a > b*b*b + c * c*c + d * d*d)
						continue;
					if (a*a*a == b * b*b + c * c*c + d * d*d)
						printf("Cube = %d, Triple = (%d,%d,%d)\n", a, b, c, d);
				}
			}
		}
	}
	return 0;
}

8.5 熄灯问题

#include <cstdio>
int puzzle[6][8] = { 0 }, press[6][8] = { 0 };

bool guess() {
	for (int r = 1; r < 5; r++) {
		for (int c = 1; c < 7; c++)
			press[r + 1][c] = (puzzle[r][c] + press[r][c] + press[r - 1][c] + press[r][c - 1] + press[r][c + 1]) % 2;
	}
	for (int c = 1; c < 7; c++)
		if (puzzle[5][c] != (press[5][c] + press[5][c - 1] + press[5][c + 1] + press[4][c]) % 2)
			return false;
	return true;
}

void enumate() {
	int c;
	for (c = 1; c < 7; c++)
		press[1][c] = 0;
	while (guess() == false) {
		press[1][1]++;
		c = 1;
		while (press[1][c] > 1) {
			press[1][c] = 0;
			c++;
			press[1][c]++;
		}
	}
	return;
}

int main() {
	for (int i = 1; i <= 5; i++)
		for (int j = 1; j <= 6; j++)
			scanf("%d", &puzzle[i][j]);
	enumate();
	for (int i = 1; i <= 5; i++) {
		for (int j = 1; j <= 6; j++)
			printf("%d ", press[i][j]);
		printf("\n");
	}
}

8.6 恼人的小青蛙

#include <cstdio>
#include <stdlib.h>
#include <algorithm>>
using namespace std;

struct PLANT {
	int x, y;
}plants[5010];

int row, col;
int n;

bool cmp(PLANT a, PLANT b) {
	if (a.x != b.x)
		return a.x < b.x;
	else
		return a.y < b.y;
}

int SearchPath(PLANT secPlant, int dx, int dy) {
	PLANT plant;
	int steps;
	plant.x = secPlant.x + dx;
	plant.y = secPlant.y + dy;
	steps = 2;
	while (plant.x <= row && plant.x >= 1 && plant.y <= col && plant.y >= 1) {
		if (!binary_search(plants, plants + n, plant, cmp)) {
			steps = 0;
			break;
		}
		plant.x += dx;
		plant.y += dy;
		steps++;
	}
	return steps;
}

int main() {
	scanf("%d %d", &row, &col);
	int dx, dy, px, py, steps = 0, max = 2;
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
		scanf("%d %d", &plants[i].x, &plants[i].y);
	sort(plants, plants + n,cmp);
	for (int i = 0; i < n - 2; i++) {
		for (int j = i + 1; j < n - 1; j++) {
			dx = plants[j].x - plants[i].x;
			dy = plants[j].y - plants[i].y;
			px = plants[i].x - dx;
			py = plants[i].y - dy;
			if (px <= row && px >= 1 && py <= col && py >= 1)
				continue;
			if (plants[i].x + (max - 1)*dx > row)
				break;
			py = plants[i].y + (max - 1)*dy;
			if (py > col || py < 1)
				continue;
			steps = SearchPath(plants[j], dx, dy);
			if (steps > max)
				max = steps;
		}
	}
	if (max == 2)
		max = 0;
	printf("%d", max);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值