返回顶部

AtCoder Beginner Contest 183

A


#include <cstdio>
using namespace std;

int main()
{
	int n;
	scanf("%d", &n);
	printf("%d\n", n >= 0 ? n : 0);	
	return 0;
}

B

三角形相似,变量直接用double存


#include <cstdio>
using namespace std;
double sx, sy, gx, gy;

int main()
{
	scanf("%lf%lf%lf%lf", &sx, &sy, &gx, &gy);
	double res = (sy * gx + gy * sx) / (gy + sy);
	printf("%lf\n", res);
	return 0;
}

C


#include <cstdio>
using namespace std;
const int N = 10;

int n, k, res, t[N][N];
bool vis[N];

void dfs(int u, int cnt, int sum)
{
	if(cnt == n && sum + t[u][1] == k)
	{
		res ++;
		return;
	} 
	for(int i = 2; i <= n; ++ i)
	{
		if(!vis[i])
		{
			vis[i] = 1;
			dfs(i, cnt + 1, sum + t[u][i]);
			vis[i] = 0;
		} 
	}
	
}

int main()
{
	scanf("%d%d", &n, &k);
	for(int i = 1; i <= n; ++ i) 
		for(int j = 1; j <= n; ++ j)
			scanf("%d", &t[i][j]);
	dfs(1, 1, 0);	
	printf("%d\n", res);
	return 0;
} 

D

\(i\)表示\(i - 1\) -> \(i\)这段时间,维护一下差分序列即可.


#include <cstdio>
using namespace std;
typedef long long LL;
const int N = 2e5 + 20;

LL a[N];
int n, w;

int main()
{
	scanf("%d%d", &n, &w);
	for(int i = 1; i <= n; ++ i)
	{
		int s, t, p;
		scanf("%d%d%d", &s, &t, &p);
		a[s + 1] += p;
		a[t + 1] -= p;
	}	
	for(int i = 1; i < N; ++ i)
	{
		a[i] += a[i - 1];
		if(a[i] > w)
		{
			printf("No\n");
			return 0;
		}
	}
	printf("Yes\n");
	return 0;
}

E

\(f[i][j]\)表示走到\((i,j)\)的方案数,用前缀和优化一下状态转移,需要做三个前缀和,分别为从左方、上方、左上方转移.


#include <cstdio>
using namespace std;
const int N = 2e3 + 20;
const int MOD = 1e9 + 7;

int n, m;
char s[N][N];
int f[N][N];
int r[N][N], c[N][N], t[N][N]; 

int main()
{
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++ i)
		scanf("%s", s[i] + 1);
	t[1][1] = c[1][1] = r[1][1] = f[1][1] = 1;
	for(int i = 1; i <= n; ++ i)
		for(int j = 1; j <= m; ++ j)
		{
			if(s[i][j] != '#')	
			{
				if(i - 1 > 0) f[i][j] = (f[i][j] + r[i - 1][j]) % MOD;
				if(j - 1 > 0) f[i][j] = (f[i][j] + c[i][j - 1]) % MOD;
				if(i - 1 > 0 && j - 1 > 0) f[i][j] = (f[i][j] + t[i - 1][j - 1]) % MOD;
				r[i][j] = (r[i - 1][j] + f[i][j]) % MOD;
				c[i][j] = (c[i][j - 1] + f[i][j]) % MOD;
				t[i][j] = (t[i - 1][j - 1] + f[i][j]) % MOD;
			}
			else r[i][j] = c[i][j] = t[i][j] = 0;
		}
	printf("%d\n", f[n][m]);
	return 0;
}

F

并查集的启发式合并,按照当前集合的学生所在班级的数目合并


#include <cstdio>
#include <unordered_map>
using namespace std;
const int N = 2e5 + 20;

int n, q;
int fa[N];
unordered_map<int, int> cnt[N];

int find(int x)
{
	if(fa[x] != x) fa[x] = find(fa[x]);
	return fa[x]; 
}

void merge(int x, int y)
{
	int fx = find(x), fy = find(y);
	if(fx == fy) return;
	if(cnt[fx].size() > cnt[fy].size()) swap(fx, fy);
	fa[fx] = fy;
	for(auto t: cnt[fx])
		cnt[fy][t.first] += t.second;
}

int main()
{
	scanf("%d%d", &n, &q);
	for(int i = 1; i <= n; ++ i) 
	{
		int x;
		scanf("%d", &x);
		cnt[i][x] ++;
		fa[i] = i;
	}
	while(q -- )
	{
		int op, a, b;
		scanf("%d%d%d", &op, &a, &b);
		if(op == 1) merge(a, b);
		else 
		{
			int k = find(a);
			printf("%d\n", cnt[k][b]);
		} 
	}
	return 0;
}

2020.11.21

posted @ 2020-11-21 19:28  __October  阅读(80)  评论(0编辑  收藏  举报