Day6 1.1

1.孤独的照片
每日一题
Farmer John 最近购入了 N 头新的奶牛,每头奶牛的品种是更赛牛(Guernsey)或荷斯坦牛(Holstein)之一。

奶牛目前排成一排,Farmer John 想要为每个连续不少于三头奶牛的序列拍摄一张照片。

然而,他不想拍摄这样的照片,其中只有一头牛的品种是更赛牛,或者只有一头牛的品种是荷斯坦牛——他认为这头奇特的牛会感到孤立和不自然。

在为每个连续不少于三头奶牛的序列拍摄了一张照片后,他把所有「孤独的」照片,即其中只有一头更赛牛或荷斯坦奶牛的照片,都扔掉了。

给定奶牛的排列方式,请帮助 Farmer John 求出他会扔掉多少张孤独的照片。

如果两张照片以不同位置的奶牛开始或结束,则认为它们是不同的。

输入格式
输入的第一行包含 N。

输入的第二行包含一个长为 N 的字符串。如果队伍中的第 i 头奶牛是更赛牛,则字符串的第 i 个字符为 G。否则,第 i 头奶牛是荷斯坦牛,该字符为 H。

输出格式
输出 Farmer John 会扔掉的孤独的照片数量。

数据范围
3≤N≤5×105
输入样例:
5
GHGHG
输出样例:
3
样例解释
这个例子中的每一个长为 3 的子串均恰好包含一头更赛牛或荷斯坦牛——所以这些子串表示孤独的照片,并会被 Farmer John 扔掉。

所有更长的子串(GHGH、HGHG 和 GHGHG)都可以被接受。

思路:
首先想到的方法是暴力枚举,尝试了一遍之后TL了
正解是:枚举每一头牛,找出当前这个点的左边相邻的连续不同的牛 * 右边的相邻连续不同的牛 + 左边的不同牛的长度 - 1 + 右边不同的牛的长度 - 1;
代码:

#include<cstdio>
#include<iostream>
using namespace std;
int a[1000005];
int main()
{
	long long sum = 0;
	int m;
	cin >> m;
	char c;
	for (int i = 1; i <= m; i++)
	{
		cin >> c;
		if (c == 'G')
			a[i] = 1;
	}
	for (int i = 1; i <= m; i++)
	{
		long long ll = 0, rr = 0;
		int l = i - 1, r = i + 1;
		while (l > 0)
		{
			if (a[l] == a[i])
				break;
			ll++;
			l--;
		}
		while (r < m + 1)
		{
			if (a[r] == a[i])
				break;
			rr++;
			r++;
		}
		sum += ll * rr;
		if (ll != 0)
			sum += ll - 1;
		if (rr != 0)
			sum += rr - 1;
	}
	cout << sum;
}

2.统计次数
给定两个正整数 n 和 k,求从 1 到 n 这 n 个正整数的十进制表示中 k 出现的次数。

输入格式
共一行,包含两个整数 n 和 k。

输出格式
输出一个整数,表示答案。

数据范围
1≤n≤106,
1≤k≤9
输入样例:
12 1
输出样例:
5
样例解释
从 1 到 12 这些整数中包含 1 的数字有 1,10,11,12,一共出现了 5 次 1。
思路:
假设n=1000 k=3
在 0~9 中,k出现了1次:3
在0~99中,k出现了20次:
03 13 23 43 53 63 73 83 93
30 31 32 34 35 36 37 38 39
33
其中 3 在个位出现10次,在十位出现10次
在0~999中,k出现了300次
其中在个位以及十位出现了200次,在百位出现了100次
很容易推出规律
0~99 中k出现次数= 0~9 中k出现次数 * 10 + 10
0~999 中k出现次数= 0~99 中k出现次数 * 10 + 100
以此类推
即可以推出每一位数的出现次数
在求出n的每一位数,进行处理即可求出k出现次数
代码:

#include<cstdio>
#include<iostream>
using namespace std;
int a[10];
int main()
{
	int n, k;
	int t = 1;
	int tt = 0;
	int pt = 0;
	cin >> n >> k;
	while (n >= t * 10)
	{
		tt = tt * 10 + t;
		t *= 10;
		a[++pt] = tt;
	}
	int sum = 0;
	while (n)
	{
		if (n < t)
		{
			t /= 10;
			pt--;
			continue;
		}
		if (n / t > k)
			sum += (n / t) * a[pt] + t;
		else if (n / t == k)
			sum += (n / t) * a[pt] + n % t + 1;
		else
			sum += (n / t) * a[pt];
		pt--;
		n = n % t;
		t /= 10;
	}
	cout << sum;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值