【2021夏纪中游记】2021.8.14模拟赛

比赛概括:

\(\mathrm{sum}=26.7+0+40+0\)

T1 [USACO 2021 US Open]Do You Know Your ABCs? S:

题目大意:

思路:

暴力把输入的数按升序填入 \(A,B,C,A+B,A+C,B+C,A+B+C\),因为有的时候 \(C > A+B\),换个位子就行。

代码:

const int N = 10;

inline ll Read()
{
	ll x = 0, f = 1;
	char c = getchar();
	while (c != '-' && (c < '0' || c > '9')) c = getchar();
	if (c == '-') f = -f, c = getchar();
	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
	return x * f;
}

int n;
int r[N], ans;
int vis[N];

struct ANS
{
	int a, b, c;
	ANS(int A, int B, int C) {a = A, b = B, c = C;}
	bool operator < (const ANS &A) const
	{
		return a < A.a || (b < A.b && a == A.a) || (c < A.c && b == A.b && a == A.a); 
	}
};
map <ANS, int> hash;

bool AeB(int a, int b) {return a == 0 || a == b;} 

bool check(int a, int b, int c)
{
	return a > 0 && b >= a && c >= b && AeB(vis[1], a) && AeB(vis[2], b) && AeB(vis[3], c) && AeB(vis[4], a + b) && AeB(vis[5], a + c) && AeB(vis[6], b + c) && AeB(vis[7], a + b + c) && !hash[ANS(a, b, c)];
}

int ch[5][4] = {{}, {2, 3}, {1, 0, 3}, {0, 1, 2}};
int a[5];
int TwoSame(int x, int y, int z)
{
	a[x] = vis[x], a[y] = vis[y];
	bool flag = 1;
	if (vis[z]) a[z] = vis[z], flag = 0;
	else
		for (int i = 4; i <= 6; i++)
		{
			if (i == 7 - z || !vis[i]) continue;
			a[z] = vis[i] - vis[ch[z][i-4]];
			flag = 0; break;
		}
	if (flag)
		a[z] = vis[7] - vis[x] - vis[y];
	if (check(a[1], a[2], a[3])) hash[ANS(a[1], a[2], a[3])] = 1, ans++;
}
int OneSame(int x, int y, int z)
{
	a[x] = vis[x];
	for (int i = 4; i <= 6; i++)
	{
		if (i == 7 - x || !vis[i]) continue;
		a[ch[x][i-4]] = vis[i] - vis[x];
	}
	if (vis[7 - x])
		if (a[y]) a[z] = vis[7 - x] - a[y];
		else a[y] = vis[7 - x] - a[z];
	if (check(a[1], a[2], a[3])) hash[ANS(a[1], a[2], a[3])] = 1, ans++;
}

void Check()
{
	a[1] = a[2] = a[3] = 0;
	if (vis[1] && vis[2]) {TwoSame(1, 2, 3); return;} 
	if (vis[1] && vis[3]) {TwoSame(1, 3, 2); return;} 
	if (vis[3] && vis[2]) {TwoSame(2, 3, 1); return;} 
	if (vis[1]) {OneSame(1, 2, 3); return;} 
	if (vis[2]) {OneSame(2, 1, 3); return;} 
	if (vis[3]) {OneSame(3, 1, 2); return;} 
	int v7 = (vis[4] + vis[5] + vis[6]) / 2;
	a[1] = v7 - vis[6];
	a[2] = v7 - vis[5];
	a[3] = v7 - vis[4];
	if (check(a[1], a[2], a[3])) hash[ANS(a[1], a[2], a[3])] = 1, ans++;
}

void dfs(int x, int k)
{
	if (x == 8 && k != n + 1) return;
	if (k == n + 1)
	{
		Check();
		vis[3] ^= vis[4] ^= vis[3] ^= vis[4];
		Check();
		vis[3] ^= vis[4] ^= vis[3] ^= vis[4];
		return ;
	}
	dfs(x + 1, k);
	vis[x] = r[k];
	dfs(x + 1, k + 1);
	vis[x] = 0;
}

int main()
{
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	for (int t = Read(); t--; )
	{
		memset (vis, 0, sizeof vis);
		hash.clear();
		ans = 0;
		n = Read();
		for (int i = 1; i <= n; i++) 
			r[i] = Read();
		sort (r + 1, r + 1 + n);
		dfs(1, 1);
		printf ("%d\n", ans);
	}
	return 0;
}

T2 [USACO 2021 US Open, Silver]Acowdemia:

题目大意:

思路:

二分 \(h\) 指数。

代码:

const int N = 1e5 + 10;

inline ll Read()
{
	ll x = 0, f = 1;
	char c = getchar();
	while (c != '-' && (c < '0' || c > '9')) c = getchar();
	if (c == '-') f = -f, c = getchar();
	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
	return x * f;
}

ll n, k, L;
int a[N]; 

bool check(int x)
{
	ll cnt = 0;
	for (int i = n - x + 1; i <= n; i++)
	{
		if (x <= a[i]) break;
		if (x - a[i] > k) return 0;
		cnt += x - a[i];
	}
	return cnt <= k * L;
}

int main()
{
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	n = Read(), k = Read(), L = Read();
	for (int i = 1; i <= n; i++) a[i] = Read();
	sort (a + 1, a + 1 + n);
	int l = 1, r = n, ans = 0;
	while (l <= r)
	{
		int mid = l + r >> 1;
		if (check(mid)) l = mid + 1, ans = mid;
		else r = mid - 1;
	}
	printf ("%d\n", ans);
	return 0;
}

T3 [USACO 2021 US Open, Gold]United Cows of Farmer John:

题目大意:

枚举点 \(i\) 左右最远能到达的值 \(l_i,r_i\)。那么如果 \([L,R]\) 要合法,就有 \(L+1\leq R\leq r_L,l_R\leq L\)。典型二维偏序。

代码:

#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ZYC using
#define AK namespace
#define IOI std
#define ll long long

ZYC AK IOI;

const int N = 2e5 + 10;

inline ll Read()
{
	ll x = 0, f = 1;
	char c = getchar();
	while (c != '-' && (c < '0' || c > '9')) c = getchar();
	if (c == '-') f = -f, c = getchar();
	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
	return x * f;
}

int n;
int a[N], lst[N], L[N], R[N];
ll ans;

int t[N];
void modify(int x, int val) {for (; x <= n; x += x & -x) t[x] += val;}
int query(int x)
{
	int ans = 0;
	for (; x; x -= x & -x) ans += t[x];
	return ans;
}
vector <int> Dame[N];

int main()
{
	n = Read();
	for (int i = 1; i <= n; lst[a[i]] = i, i++) 
		a[i] = Read(), L[i] = lst[a[i]] + 1;
	memset (lst, 0, sizeof lst);
	for (int i = 1; i <= n; i++) lst[i] = n + 1;
	for (int i = n; i; lst[a[i]] = i, i--) 
		R[i] = lst[a[i]] - 1;
	for (int i = 1; i <= n; i++)
		modify(i, 1), Dame[L[i]].push_back(i);
	for (int l = n - 1; l; l--)
	{
		for (int i = 0; i < Dame[l + 1].size(); i++)
			modify(Dame[l + 1][i], -1);
		ans += query(R[l]) - query(l); //[l+1,R[l]]
	}
	printf ("%lld", ans);
	return 0;
}

T4 [USACO 2021 US Open, Silver]Maze Tac Toe:

题目大意:

思路:

暴力搜索。

代码:

const int N = 30, M = 5, K = 20010;

inline ll Read()
{
	ll x = 0, f = 1;
	char c = getchar();
	while (c != '-' && (c < '0' || c > '9')) c = getchar();
	if (c == '-') f = -f, c = getchar();
	while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
	return x * f;
}

int n;
int A[M][M], win[K], pw[K];
bool vis[N][N][K], Vis[K];
char a[N][N * 3];

bool Win(int S)
{
	for (int i = 1; i <= 3; i++)
		for (int j = 1; j <= 3; j++)
		{
			A[i][j] = S % 3;
			S /= 3;
		}
	for (int i = 1; i <= 3; i++)
	{
		if (A[i][1] == 1 && A[i][2] == 2 && A[i][3] == 2) return 1;
		if (A[i][1] == 2 && A[i][2] == 2 && A[i][3] == 1) return 1;
		if (A[1][i] == 1 && A[2][i] == 2 && A[3][i] == 2) return 1;
		if (A[1][i] == 2 && A[2][i] == 2 && A[3][i] == 1) return 1;
	}
	if (A[1][1] == 1 && A[2][2] == 2 && A[3][3] == 2) return 1;
	if (A[1][1] == 2 && A[2][2] == 2 && A[3][3] == 1) return 1;
	if (A[1][3] == 1 && A[2][2] == 2 && A[3][1] == 2) return 1;
	if (A[1][3] == 2 && A[2][2] == 2 && A[3][1] == 1) return 1;
	return 0;
}

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int Modify(int S, char st, int x, int y)
{
	x = 3 * x + y;
	if ((S / pw[x]) % 3) return S;
	return S + (st == 'M'? 1: 2) * pw[x];
}

int ans;
void dfs(int x, int y, int S)
{
	if (a[x][3 * y + 1] == 'O' || a[x][3 * y + 1] == 'M')
		S = Modify(S, a[x][3 * y + 1], a[x][3 * y + 2] - '1', a[x][3 * y + 3] - '1');
	if (vis[x][y][S]) return ;
	vis[x][y][S] = 1;
	if (win[S])
	{
		ans += !Vis[S], Vis[S] = 1;
		return;
	}
	for (int i = 0; i < 4; i++)
	{
		int X = x + dx[i], Y = y + dy[i];
		if (a[X][3 * Y + 1] == '#' || a[X][3 * Y + 1] == '\0') continue;
		dfs (X, Y, S);
	}
}

int main()
{
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	n = Read();
	pw[0] = 1;
	for (int i = 1; i <= 9; i++) pw[i] = pw[i - 1] * 3;
	for (int i = 0; i < pw[9]; i++)
		win[i] = Win(i);
	for (int i = 1; i <= n; i++)
		scanf ("%s", a[i] + 1);
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			if (a[i][3 * j + 1] == 'B')
				dfs(i, j, 0);
	printf ("%d", ans);
	return 0;
}
posted @ 2021-08-16 07:51  Jayun  阅读(70)  评论(0编辑  收藏  举报