AtCoder Beginner Contest 177 A~D 题解

A - Don’t be late

题目大意

Takahashi要和Aoki见面。
他们计划在距离Takahashi家 D D D米的地方 T T T分钟后见面。
Takahashi将立即出门并以 S S S米/分钟的速度朝见面地点走去。
Takahashi能按时到达吗?

1 ≤ D ≤ 10000 1\le D\le 10000 1D10000
1 ≤ T ≤ 10000 1\le T\le 10000 1T10000
1 ≤ S ≤ 10000 1\le S\le 10000 1S10000

输入格式

D   T   S D~T~S D T S

输出格式

如果Takahashi提前或准时到达此地,输出Yes;否则输出No

样例

DTS输出
10001580Yes
200020100Yes
1000011No

分析

判断 D S ≤ T \frac D S\le T SDT(简化后为 T S ≥ D TS\ge D TSD)即可。

代码

#include <cstdio>
using namespace std;

int main(int argc, char** argv)
{
	int d, t, s;
	scanf("%d%d%d", &d, &t, &s);
	puts(t * s >= d? "Yes": "No");
	return 0;
}

B - Substring

题目大意

给你两个字符串 S S S T T T
请你修改 S S S中的一些字符(可以不修改)使得 T T T S S S的字串。
至少需要修改多少个字符?
子串:如,xxxyxxxy的子串,但不是xxyxx的子串。

1 ≤ ∣ T ∣ ≤ ∣ S ∣ ≤ 1000 1\le |T|\le |S|\le 1000 1TS1000
S S S T T T都由小写英文字母组成。

输入格式

S   T S~T S T

输出格式

一行,即至少需要修改的字符个数。

样例

样例输入1

cabacc
abc

样例输出1

1

cabacc-abc

样例输入2

codeforces
atcoder

样例输出2

6

codeforces-atcoder-sample

分析

我们只要将 T T T S S S中滚动匹配,寻找不同的字母数量的最小值即可。

代码

其实这就是枚举 😃
注意:如果按下面的代码写,最开始一定要特判 S S S T T T长度相等的情况!

#include <cstdio>
#define maxn 1005
using namespace std;

char s[maxn], t[maxn];

int main(int argc, char** argv)
{
	scanf("%s%s", s, t);
	int tlen = 0, ans = maxn;
	for(; t[tlen]; tlen++);
	if(s[tlen] == '\0')
	{
		ans = 0;
		for(int i=0; i<tlen; i++)
			if(s[i] != t[i])
				ans ++;
		printf("%d\n", ans);
		return 0;
	}
	for(int i=0; s[i+tlen]; i++)
	{
		int cnt = 0;
		for(int j=0; j<tlen; j++)
			if(s[i + j] != t[j])
				cnt ++;
		if(cnt < ans) ans = cnt;
	}
	printf("%d\n", ans);
	return 0;
}

C - Sum of product of pairs

题目大意

给定 N N N个整数 A 1 , A 2 , … , A N A_1,A_2,\dots,A_N A1,A2,,AN
输出 ∑ i = 1 N − 1 ∑ j = i + 1 N A i A j m o d    ( 1 0 9 + 7 ) {\sum\limits_{i=1}^{N-1}\sum\limits_{j=i+1}^NA_iA_j} \mod {(10^9+7)} i=1N1j=i+1NAiAjmod(109+7),即符合 1 ≤ i < j ≤ N 1\le i \lt j\le N 1i<jN的所有 ( i , j ) (i,j) (i,j) A i A j A_iA_j AiAj的和,对 ( 1 0 9 + 7 ) (10^9 + 7) (109+7)取模。

输入格式

N N N
A 1   A 2   …   A N A_1~A_2~\dots~A_N A1 A2  AN

输出格式

输出一行,即 ∑ i = 1 N − 1 ∑ j = i + 1 N A i A j m o d    ( 1 0 9 + 7 ) {\sum\limits_{i=1}^{N-1}\sum\limits_{j=i+1}^NA_iA_j} \mod {(10^9+7)} i=1N1j=i+1NAiAjmod(109+7)

样例

样例输入1

3
1 2 3

样例输出1

11

1 × 2 + 1 × 3 + 2 × 3 = 11 1\times2+1\times3+2\times3=11 1×2+1×3+2×3=11

样例输入2

4
141421356 17320508 22360679 244949

样例输出2

437235829

不要忘记对 ( 1 0 9 + 7 ) (10^9 + 7) (109+7)取模!

分析

我们需要将题目中的公式转化一下:
∑ i = 1 N − 1 ∑ j = i + 1 N A i A j m o d    ( 1 0 9 + 7 ) {\sum\limits_{i=1}^{N-1}\sum\limits_{j=i+1}^NA_iA_j} \mod {(10^9+7)} i=1N1j=i+1NAiAjmod(109+7)
( ∑ i = 2 N ∑ j = 0 i − 1 A i A j ) m o d    ( 1 0 9 + 7 ) {(\sum\limits_{i=2}^{N}\sum\limits_{j=0}^{i-1}A_iA_j)} \mod {(10^9+7)} (i=2Nj=0i1AiAj)mod(109+7)
∑ i = 2 N A i ( ∑ j = 0 i − 1 A j ) m o d    ( 1 0 9 + 7 ) {\sum\limits_{i=2}^{N}A_i(\sum\limits_{j=0}^{i-1}A_j)} \mod {(10^9+7)} i=2NAi(j=0i1Aj)mod(109+7)
这时,我们只需循环遍历 i i i,再设置一个变量记录 ∑ j = 0 i − 1 A j \sum\limits_{j=0}^{i-1}A_j j=0i1Aj即可。

代码

可以输入时直接处理。
虽然要取模,但是还要使用long long

#include <cstdio>
#define maxn 200005
#define MOD 1000000007LL
using namespace std;

typedef long long LL;

int main(int argc, char** argv)
{
	int n;
	LL sum, res = 0LL;
	scanf("%d%lld", &n, &sum);
	while(--n) // 循环 (n-1) 次
	{
		LL x;
		scanf("%lld", &x);
		res += sum * x;
		sum += x;
		res %= MOD, sum %= MOD;
	}
	printf("%lld\n", res);
	return 0;
}

D - Friends

题目大意

N N N个人,编号分别为 1 1 1 N N N
给你 M M M个关系,第 i i i个关系为“ A i A_i Ai号人和 B i B_i Bi号人是朋友。”(关系可能会重复给出)。
如果 X X X Y Y Y是朋友、 Y Y Y Z Z Z是朋友,则 X X X Z Z Z也是朋友。
Takahashi大坏蛋想把这 N N N个人进行分组,使得每组中的人互不为朋友。他至少要分多少组?

2 ≤ N ≤ 2 × 1 0 5 2\le N\le 2\times10^5 2N2×105
0 ≤ M ≤ 2 × 1 0 5 0\le M\le 2\times10^5 0M2×105
1 ≤ A i , B i ≤ N 1\le A_i,B_i\le N 1Ai,BiN
A i ≠ B i A_i \ne B_i Ai=Bi

输入格式

N   M N~M N M
A 1   B 1 A_1~B_1 A1 B1
A 2   B 2 A_2~B_2 A2 B2
⋮ \vdots
A M   B M A_M~B_M AM BM

输出格式

输出答案。

样例

样例输入1

5 3
1 2
3 4
5 1

样例输出1

3

分为三组: { 1 , 3 } \{1,3\} {1,3} { 2 , 4 } \{2,4\} {2,4} { 5 } \{5\} {5}可以达到目标。

样例输入2

4 10
1 2
2 1
1 2
2 1
1 2
1 3
1 4
2 3
2 4
3 4

样例输出2

4

请注意重复的关系。

样例输入3

10 4
3 1
4 1
5 9
2 6

样例输出3

3

分析

这道题可以先分出一个个朋友圈,再从朋友圈的人数中取最大值并输出即可。

代码

“分出朋友圈”这个操作可以使用dfs/bfs(不需要去重),当然,并查集也是可以的(需要去重)。我选择的是bfs

#include <cstdio>
#include <queue>
#include <vector>
#define maxn 200005
using namespace std;

vector<int> G[maxn];
bool vis[maxn];

int bfs(int x)
{
	queue<int> q;
	q.push(x);
	int cnt = 0;
	while(!q.empty())
	{
		x = q.front(); q.pop();
		if(vis[x]) continue;
		vis[x] = true, cnt ++;
		for(int v: G[x])
			q.push(v);
	}
	return cnt;
}

int main(int argc, char** argv)
{
	int n, m;
	scanf("%d%d", &n, &m);
	for(int i=0; i<m; i++)
	{
		int x, y;
		scanf("%d%d", &x, &y);
		G[x].push_back(y);
		G[y].push_back(x);
	}
	int ans = bfs(0);
	for(int i=1; i<n; i++)
		if(!vis[i])
		{
			int cnt = bfs(i);
			if(cnt > ans)
				ans = cnt;
		}
	printf("%d\n", ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值