【数据结构与算法】学习笔记-《算法笔记》-6

害死人不偿命的(3n+1)猜想

#include "stdafx.h"
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;

int main()
{
	int n;
	int i = 0;
	scanf("%d", &n);
	while (n - 1)
	{
		if (fmod(n, 2))
		{
			n = 3*n + 1;
		}
		n = n / 2;
		i++;
	}
	printf("%d", i);
	return 0;
}

这里while中的条件可以改为while(n!=1)
fmod 函数可以改成%:if(n%2==0)

挖掘机技术哪家强

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

int main()
{
	int n,m=0,maxnum=0,maxscore=0,score;
	int a[1000] = { 0 };
	int b[1000] = { 0 };
	scanf("%d", &n);
	for(int i=0;i<n;i++)
	{
		scanf("%d %d", &a[i], &score);
		b[a[i]] += score;
		if (a[i] > m)	m = a[i];
	}
	for (int i = 0; i < m; i++)
	{
		if (b[i] > maxscore)
		{
			maxscore = b[i];
			maxnum = i;
		}
	}
	printf("%d %d", maxnum, maxscore);
	return 0;
}

这里题目要求的是N<100000,但是这样会造成数据溢出,程序改成1000正常运行,显然不符合题意,把a[100000]的初始化去掉,只留下b数组的初始化。

**练习**

剩下的树

题目描述
有一个长度为整数L(1<=L<=10000)的马路,可以想象成数轴上长度为L的一个线段,起点是坐标原点,在每个整数坐标点有一棵树,即在0,1,2,…,L共L+1个位置上有L+1棵树。
现在要移走一些树,移走的树的区间用一对数字表示,如 100 200表示移走从100到200之间(包括端点)所有的树。
可能有M(1<=M<=100)个区间,区间之间可能有重叠。现在要求移走所有区间的树之后剩下的树的个数。

输入 两个整数L(1<=L<=10000)和M(1<=M<=100)。
接下来有M组整数,每组有一对数字。

输出 可能有多组输入数据,对于每组输入数据,输出一个数,表示移走所有区间的树之后剩下的树的个数。

#include <cstdio>
#include <cstring>
#include<cmath>

int main()
{
	int L, M,q,p;
	int a[10001] = { 0 };
	while (scanf("%d %d", &L, &M), L || M)
	{
		int sum = 0;
		//memset(a, 0, sizeof(a));
		for (int i = 0; i <= L; i++)
		{
			a[i] = 1;
		}
		while (M--)
		{
			scanf("%d %d", &q, &p);
			for (int j = q; j <= p; j++)
			{
				a[j] = 0;
			}
		}
		for (int i = 0; i <= L; i++)
		{
			sum += a[i];
		}
		printf("%d\n", sum);
	}
	return 0;
}

A+B

题目描述
给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号","隔开。 现在请计算A+B的结果,并以正常形式输出。
输入 输入包含多组数据数据,每组数据占一行,
由两个整数A和B组成(-109 < A,B < 109)。
输出 请计算A+B的结果,并以正常形式输出,每组数据占一行。

啊啊啊啊不会!!!

特殊乘法

题目描述
写个算法,对2个小于1000000000的输入,求结果。
特殊乘法举例:123 * 45 = 14 +15 +24 +25 +34+35
输入
两个小于10000000000的数
输出
输入可能有多组数据,对于每一组数据,输出Input中的两个数按照题目要求的方法进行运算后得到的结果。

// ConsoleApplication1.cpp: 定义控制台-应用程序的入口点。
//
#include "stdafx.h"
#include <cstdio>
#include <cstring>
#include <cmath>

int main()
{
	int a[10] = { 0 }, b[10] = { 0 };
	long long int num1, num2;
	long temp;
	while (scanf("%lld %lld", &num1, &num2) != EOF)
	{
		for (int i = 0; i<10; i++)
		{
			temp = fmod(num1, pow(10, i + 1));
			a[i] = (temp - fmod(temp, pow(10, i))) / (pow(10, i));
			temp = fmod(num2, pow(10, i + 1));
			b[i] = (temp - fmod(temp, pow(10, i))) / (pow(10, i));
		}
		int result = 0;
		for (int i = 0; i<10; i++)
		{
			for (int j = 0; j<10; j++)
			{
				result += a[i] * b[j];
			}
		}
		printf("%d\n", result);
	}
	return 0;
}

在做这道题的时候,遇到了一些问题,比如int/long int的范围都不包括最大数999999999,所以在设置数据类型的时候应该设置为long long int。

思考:这道题还有没有其他的解法?比如用字符串?

#include <cstdio>
#include <cstring>
#include <cmath>

int main()
{
	char a[10] = { 0 }, b[10] = { 0 };
	int result = 0;
	int m, n;
	while (scanf("%s %s", a, b) != EOF)
	{
		for (int i = 0; i<strlen(a); i++)
		{
			for (int j = 0; j<strlen(b); j++)
			{
				m = a[i] - '0';
				n = b[j] - '0';
				result +=( a[i]-'0') *( b[j]-'0');
			}
		}
		printf("%d\n", result);
	}
}

借鉴别人的方法写出了如上代码,其中要注意的一点是

		for (int i = 0; i<strlen(a); i++)

这行代码中,如果直接写成i<10;猜测会导致读入’\0’,使最后结果出错。

比较奇偶数个数

题目描述
第一行输入一个数,为n,第二行输入n个数,这n个数中,如果偶数比奇数多,输出NO,否则输出YES。
输入
输入有多组数据。
每组输入n,然后输入n个整数(1<=n<=1000)。
输出
如果偶数比奇数多,输出NO,否则输出YES。

#include <cstdio>
#include <cstring>
#include <cmath>

int main()
{
	int n,num;
	while (scanf("%d", &n) != EOF)
	{
		int n1 = 0, n2 = 0;
		while (n--)
		{
			scanf("%d", &num);
			if (fmod(num, 2))	n1++;
			else n2++;
		}
		if (n2 > n1)	printf("NO\n");
		else printf("YES\n");
	}
	return 0;
}

Shortest Distance

题目描述
The task is really simple: given N exits on a highway which forms a simple cycle, you are supposed to tell the shortest distance between any pair of exits.
输入
Each input file contains one test case. For each case, the first line contains an integer N (in [3, 105]), followed by N integer distances D1 D2 … DN, where Di is the distance between the i-th and the (i+1)-st exits, and DN is between the N-th and the 1st exits. All the numbers in a line are separated by a space. The second line gives a positive integer M (<=104), with M lines follow, each contains a pair of exit numbers, provided that the exits are numbered from 1 to N. It is guaranteed that the total round trip distance is no more than 107.
输出
For each test case, print your results in M lines, each contains the shortest distance between the corresponding given pair of exits.
样例输入

#include <cstdio>
#include <cstring>
#include <cmath>
#define N 200000
#define M 10000
using namespace std;

int main()
{
	int n,num;
	int a[N] = { 0 }, p[M] = { 0 }, q[M] = { 0 };
	int lentha, lenthpq;
	while (scanf("%d", &n) != EOF)
	{
		int i = 0;
		while (n-i)
		{
			scanf("%d", &a[i]);
			i++;
		}
		int row;
		scanf("%d", &row);
		int j = 0;
		while (row-j)
		{
			scanf("%d %d", &p[j], &q[j]);
			if (p[j] > q[j])
			{
				int temp;
				temp = p[j];
				p[j] = q[j];
				q[j] = temp;
			}
			j++;
		}
		for (int k = 0; k < n; k++)
		{
			a[k + n] = a[k];
		}
		for (int k = 0; k < row; k++)
		{
			int dis1=0, dis2=0;
			for (int u = p[k]-1; u <=q[k]-2 ; u++)
			{
				dis1 += a[u];
			}
			for (int u = q[k] - 1; u <= p[k] + n - 2;u++)
			{
				dis2 += a[u];
			}
			if (dis1 < dis2)	printf("%d\n", dis1);
			else printf("%d\n", dis2);
		}
	}
	return 0;
}

A+B和C

题目描述
给定区间[-231, 231]内的3个整数A、B和C,请判断A+B是否大于C。
输入
输入第1行给出正整数T(<=10),是测试用例的个数。随后给出T组测试用例,每组占一行,顺序给出A、B和C。整数间以空格分隔。
输出
对每组测试用例,在一行中输出“Case #X: true”如果A+B>C,否则输出“Case #X: false”,其中X是测试用例的编号(从1开始)。

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

int main()
{
	int n;
	long long a, b, c,result;
	scanf("%d", &n);
	for (int i = 0; i<n; i++)
	{
		scanf("%lld %lld %lld", &a, &b, &c);
		result = a + b - c;
		if (result > 0)	printf("Case #%d: true\n", i + 1);
		else
			printf("Case #%d: false\n", i + 1);
	}
	return 0;
}

**部分A+B **

题目描述
题目描述
正整数A的“DA(为1位整数)部分”定义为由A中所有DA组成的新整数PA。例如:给定A = 3862767,DA = 6,则A的“6部分”PA是66,因为A中有2个6。
现给定A、DA、B、DB,请编写程序计算PA + PB。
输入
输入在一行中依次给出A、DA、B、DB,中间以空格分隔,其中0 < A, B < 1010。
输出
在一行中输出PA + PB的值。

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

int num(int a, int da)
{
	int numa = 0;
	for (int i = 1; i < 10; i++)
	{
		int k, t;
		k = pow(10, i);
		t = pow(10, i - 1);
		int m;
		m = (fmod(a, k) - fmod(a, t)) / t;
		if (m == da) 
		{
			numa++;
		}
	}
	return numa;
}

int compute(int numa,int da)
{
	int pa = 0;
	for (int i = 0; i < numa; i++)
	{
		pa += da * pow(10, i);
	}
	return pa;
}

int main()
{
	int a, b;
	int pa=0, pb=0,da,db;
	int numa = 0, numb = 0;
	while (scanf("%d %d %d %d", &a, &da, &b, &db) != EOF)
	{
		numa=num(a, da);
		numb=num(b, db);
		pa = compute(numa, da);
		pb = compute(numb, db);
		printf("%d\n", pa + pb);
	}
	return 0;
}

** 锤子剪刀布**

  • 遇到问题 不知道错在哪里==明明答案一样!

题目描述
大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示:
现给出两人的交锋记录,请统计双方的胜、平、负次数,并且给出双方分别出什么手势的胜算最大。
输入
输入第1行给出正整数N(<=105),即双方交锋的次数。随后N行,每行给出一次交锋的信息,即甲、乙双方同时给出的的手势。C代表“锤子”、J代表“剪刀”、B代表“布”,第1个字母代表甲方,第2个代表乙方,中间有1个空格。
输出
输出第1、2行分别给出甲、乙的胜、平、负次数,数字间以1个空格分隔。第3行给出两个字母,分别代表甲、乙获胜次数最多的手势,中间有1个空格。如果解不唯一,则输出按字母序最小的解。

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

int main()
{
	int n;
	char jia, yi;
	int a[2][6] = { 0 };
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		getchar();
		scanf("%c %c", &jia, &yi);
		if (jia == 'C')
		{
			if (yi == 'J')
			{
				a[0][0]++;
				a[0][3]++;
				a[1][2]++;
			}
			if (yi == 'B')
			{
				a[0][2]++;
				a[1][0]++;
				a[1][4]++;
			}
			if (yi == 'C')
			{
				a[0][1]++;
				a[1][1]++;
			}
		}
		if (jia == 'J')
		{
			if (yi == 'B')
			{
				a[0][0]++;
				a[0][5]++;
				a[1][2]++;
			}
			if (yi == 'C')
			{
				a[0][2]++;
				a[1][0]++;
				a[1][3]++;
			}
			if (yi == 'J')
			{
				a[0][1]++;
				a[1][1]++;
			}
		}
		if (jia == 'B')
		{
			if (yi == 'C')
			{
				a[0][0]++;
				a[0][4]++;
				a[1][2]++;
			}
			if (yi == 'J')
			{
				a[0][2]++;
				a[1][0]++;
				a[1][5]++;
			}
			if (yi == 'B')
			{
				a[0][1]++;
				a[1][1]++;
			}
		}
		int cha = 1;
	}
	printf("%d %d %d\n%d %d %d", a[0][0], a[0][1], a[0][2], a[1][0], a[1][1], a[1][2]);
	int output[2][2] = { 0 };
	for (int man = 0; man < 2; man++)
	{
		for (int q = 3; q <=5 ; q++)
		{
			if (a[man][q] > output[man][1])
			{
				output[man][1] = a[man][q];
				output[man][0] = q;
			}
		}
	}
	printf("\n");
	for (int k = 0;  k< 2; k++)
	{
		switch (output[k][0])
		{
		case 3: {
			printf("C ");
			break;
		}
		case 4: {
			printf("B ");
			break;
		}
		case 5: {
			printf("J");
			break;
		}
		default:
			break;
		}
		if (k == 1)
			printf("\n");
	}
	return 0;
}
发布了43 篇原创文章 · 获赞 4 · 访问量 1221

猜你喜欢

转载自blog.csdn.net/weixin_42176221/article/details/100733833