算法组第一次考核总结

虽然已经在组里学习了近一个月,但碰到难题还是被困住了,比如这次三道题把我揍得体无完肤,下面就这三道题做下总结

1.

‎有一个字符串‎S S.S S‎仅包含小写的英文字符。‎‎(10 \leq 长度(S) \leq 1,000,000)‎(10≤ ‎l‎ ‎e‎ ‎n‎ ‎g‎ ‎t‎ ‎h‎‎(‎ ‎S‎‎)‎‎≤‎‎1,000,000‎)
‎有多少个子字符串至少包含‎‎k(1 \leq k \leq 26)‎ ‎k‎‎(‎‎1‎‎≤‎ k≤26)‎不同的角色?‎

输入‎

‎有多个测试用例。输入的第一行包含一个整数‎‎T (1\leq T\leq 10)‎‎T‎‎(‎‎1‎‎≤‎T≤10)‎指示测试用例的数量。对于每个测试用例:‎

‎第一行包含字符串‎SS‎.‎
‎第二行包含一个整数‎‎k(1 \leq k \leq 26)‎‎k‎‎(‎‎1‎‎≤‎k≤26).

输出‎

‎对于每个测试用例,输出至少包含的子字符串数‎kk‎字符。‎

示例输入‎

2
abcabcabca
4
abcabcabcabc
3

‎示例输出‎

0
55
#include <stdio.h>

struct zifuchuan {
	char s[1000009];
} a[12];

int main() {
	int b[12], count = 0, count1 = 0, c[12] = {0};
	int n, p, o;
	scanf("%d", &n);

	for (p = 0; p < n; p++) {
		scanf("%s", a[p].s);
		scanf("%d", &b[p]);
	}
	int i, j, k;
	for (p = 0; p < n; p++) {

		for (i = 0; a[p].s[i] != '\0'; i ++) {
			for (k = 1; a[p].s[k + i - 1]; k ++) {
				for (j = 0; j < k; j ++) {
					for (o = 0; o < j; o++) {
						if (a[p].s[i + o] == a[p].s[i + j] )
							count++;
					}
					if (count == 0)
						count1++;
					count = 0;
				}
				if (count1 >= b[p])
					c[p]++;
				count1 = 0;
			}
		}
		printf("%d\n", c[p]);
	}
}

孩子真的不会用双指针写,马上去问。

循环的写起来比较麻烦,核心就是先罗列每个子序列,再来判断他其中不同元素的个数。

2.

‎给定一个序列 a[1],a[2],a[3]......a[n],你的工作是计算子序列的最大和。例如,给定 (6,-1,5,4,-7),此序列中的最大和为 6 + (-1) + 5 + 4 = 14。

‎输入‎:

‎输入的第一行包含一个整数 T(1<=T<=20),表示测试用例的数量。然后是 T 行,每行以数字 N(1<=N<=100000 开头),然后是 N 个整数(所有整数都在 -1000 和 1000 之间)。‎

‎输出‎:

‎对于每个测试用例,应输出两行。第一行是"案例 #:",# 表示测试用例的编号。第二行包含三个整数,序列中的最大和,子序列的起始位置,子序列的结束位置。如果有多个结果,则输出第一个结果。在两个事例之间输出一个空行。‎

示例输入‎:

2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5

‎示例输出‎:

Case 1:
14 1 4

Case 2:
7 1 6
#include <stdio.h>

int main() {
	int i, n, count, j, a[100005] = {0};
	scanf("%d", &n);
	for (j = 0; j < n; j++) {
		scanf("%d", &count);
		for (i = 0; i < count; i++)
			scanf("%d", &a[i]);
		int d = -1001, s = 0, p = 1, l, r;
		for (i = 0; i < count; i++) {
			s += a[i];
			if (s > d) {
				d = s;
				l = p;
				r = i + 1;
			}
			if (s < 0) {
				s = 0;
				p = i + 2;
			}
		}
		printf("Case %d:\n%d %d %d\n", j, d, l, r);
		if (j != n)
			printf("\n");
	}
}

核心思想就是从头开始判断两数之和,如果加上第二个数之后大于第一个数,那就让右坐标移一,如果加上之后小于零,那前面所有加过的数都不要了,重新给左坐标赋值,再进行接下来的判断,如果没有出现上述两种情况,那就先继续加,静观其变,直到出现上面两种情况时再做判断。

3.

‎超市有一套产品在售。它为在截止日期dx之前销售的每个产品x∈Prod赚取利润px,该截止日期dx以从销售开始的那一刻开始的整数时间单位数来衡量。每个产品的销售时间恰好需要一个单位。销售计划是产品销售≤生产的订购子集,因此,根据销售的订单,每个产品 x∈销售的销售在截止日期 dx 之前完成,或者就在 dx 到期时完成。卖出计划的利润是利润(卖出)=Σ‎‎x∈卖出‎‎像素。最佳销售计划是具有最大利润的时间表。‎
‎例如,考虑产品 Prod={a,b,c,d} 且 (pa,da)=(50,2), (pb,db)=(10,1), (pc,dc)=(20,2) 和 (pd,dd)=(30,1)。可能的销售时间表列于表1中。例如,计划 Sell={d,a} 显示产品 d 的销售从时间 0 开始,到时间 1 结束,而产品 a 的销售从时间 1 开始,在时间 2 结束。这些产品中的每一个都在截止日期前售出。卖出是最佳计划,其利润为80。‎
‎编写一个程序,从输入文本文件中读取产品集,并计算每组产品的最佳销售计划的‎
‎利润。‎

‎输入‎

‎一组产品以整数 0 <= n <= 10000 开头,即集合中的产品数,并继续以 n 对 pi di 整数、1 <= pi <= 10000 和 1 <= di <= 10000 开始,表示第 i 个产品的利润和销售截止日期。空白可以在输入中自由出现。输入数据以文件结尾终止,并保证正确。‎

‎输出‎

‎对于每组产品,程序在标准输出上打印该组产品的最佳销售计划的利润。每个结果都是从单独行的开头打印的。‎

‎示例输入‎

4  50 2  10 1   20 2   30 1

7  20 1   2 1   10 3  100 2   8 2
   5 20  50 10

‎示例输出‎

80
185

‎提示‎

‎示例输入包含两个产品集。第一组对表 1 中的产品进行编码。第二套适用于 7 种产品。这些产品的最佳计划利润为185。‎
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct shangpin
{
	int lirun;
	int tianshu;
}aa[10000];
int cmp(shangpin a,shangpin b)
{
	return a.lirun>b.lirun;
}
int main()
{
	int i,j,n,sum;
	while(scanf("%d",&n) != EOF){
		for(i=0;i<n;i++)
			scanf("%d%d",&aa[i].lirun,&aa[i].tianshu);
		sort(aa,aa+n,cmp);
		for(int tian=0;tian<10000;tian++)
		{
			for(i=0;i<n;i++)
			{
				if(aa[i].tianshu==tian)
					{
						sum=sum+aa[i].lirun;
						break;
					}
			}
		}
		printf("%d\n",sum-1);
		sum=1;
	}
}

这里也是借鉴了同组成员的代码,核心还是把利润大的放前面,然后把所有所在天数里利润最大的放进计划就行了。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值