SCAU2022春季个人排位赛第一场

SCAU2022春季个人排位赛第一场

写在开头

实话讲,还是习惯于自我感动了吧,总觉得自己已经够努力了,够忙了。其实对比起来自己像是什么都没做一样。这第一次排位赛要算是给自己的一个警醒吧。

第一,认真学英语;不要害怕读题,扩展词汇量。

第二,多刷思维题;换句话说,多做题。

Problem A

原题Codeforces-89A

题解

为了保证相邻的两个重量不变,两个位置而言,则可以一边 + 1 +1 +1。一边 − 1 -1 1。这样子就能保证总重量不变。而对于 n n n个位置,要保证两两相邻位置之间的总重量不变,则我们可以看成是一个$-1,+1,-1,+1\dots $的变化序列。

然后我们发现,当长度为偶数时,变化序列刚好相加为0,这说明不管怎么变化,小偷总是偷不出宝石。只有长度为奇数的时候,变化序列总和为 − 1 -1 1,这说明我们可以在这堆宝石中偷走1个宝石。通过观察可以得知,只有奇数位置的宝石可以 − 1 -1 1,所以我们能偷的最多的宝石就是 min ⁡ a i ( i & 1 = = 1 ) \min{a_i}(i\&1==1) minai(i&1==1)

而在k分钟内,每分钟我们只能进行m次操作。每次操作可以进行以下三种操作的其中一种:1、取出第 i i i位中的一颗宝石,将其放置任意一位之中;2、取出第 i i i位中一颗宝石,将其放入自己口袋;3、将口袋中的一颗宝石放置到任意位置上。

首先 k k k分钟内必须要完成 n / 2 + 1 n/2+1 n/2+1,这样子才可以偷到宝石。其次如果 k k k分钟内可以完成多次 n / 2 + 1 n/2+1 n/2+1次操作,那么也可以多偷几次宝石。

代码

// Good Good Study, Day Day AC.
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <map>
#include <algorithm> 
#include <unordered_map>
#include <unordered_set>
#define ffor(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define rrep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define ll long long
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define PII pair<int,int>
#define int long long

using namespace std;


const int N = 1e4 + 10;
int n, T, m, k;
int a[N];

void ready()
{
	IOS;
	cin >> n >> m >> k;
	ffor(i, 1, n) cin >> a[i];
}


void work()
{
	if (n % 2 == 0 || n / 2 + 1 > m) {
		cout << 0;
		return;
	}
	int ans = INF;
	ffor(i, 1, n) {
		if (i & 1) ans = min(ans, a[i]);
	}
	ans = min(ans, k * (m / (n / 2 + 1)));
	cout << ans;
}

signed main()
{
	ready();
	work();
	return 0;
}



Problem B

原题Codeforces-233B

题解

由于时间复杂度的问题,只能枚举 s ( x ) s(x) s(x),通过求根公式反推出 x 1 x_1 x1,检查 x 1 x_1 x1是否满足要求,满足则是答案。

代码

// Good Good Study, Day Day AC.
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <map>
#include <algorithm> 
#include <unordered_map>
#include <unordered_set>
#define ffor(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define rrep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define ll long long
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define PII pair<int,int>
#define int long long

using namespace std;

int n, T;


bool check_(int x, int sum)
{
	int res = 0;
	while (x) {
		res += x % 10;
		x = x / 10;
	}
	return res == sum;
}

void ready()
{
	IOS;
	cin >> n;
	ffor(i, 1,160) {
		int d = i * i + 4 * n;
		int gd = sqrt(d);
		int x = (-i + gd) / 2;
		if (d >= 0 && x * x + i * x - n == 0 && check_(x,i)) {
			cout << x;
			return;
		}
	}
	cout << -1;
}


void work()
{

}

signed main()
{
	ready();
	work();
	return 0;
}



Problem D

原题Codeforces-209A

题解

从右往左看,对于一个 R R R能够组成的答案来源于前面所有 T T T能组成的答案个数以及自身R单独作为一个。

代码

// Good Good Study, Day Day AC.
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <map>
#include <algorithm> 
#include <unordered_map>
#include <unordered_set>
#define ffor(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define rrep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define ll long long
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define PII pair<int,int>
#define int long long

using namespace std;

const int N = 1e6 + 10;
const int mod = 1e9 + 7;
int n, T;
int sum[N];
int t[3];

void ready()
{
	IOS; cin >> n;
}

int dp[N];

void work()
{
	int ans = 0;
	for (int i = 1; i <= n; i++)
	{
		if (i & 1) {
			dp[i] = (dp[i - 1] + t[0] + 1) % mod;
			t[1] = (t[1] + dp[i] - dp[i - 1] + mod) % mod;
		}
		else {
			dp[i] = (dp[i - 1] + t[1] + 1) % mod;
			t[0] = (t[0] + dp[i] - dp[i - 1] + mod) % mod;
		}
	}
	cout << dp[n] % mod;
}

signed main()
{
	ready();
	work();
	return 0;
}




Problem H

原题Codeforces-472D

题解

先将所有边保存下来,做一遍最小生成树。

随后对于两个不同的点 i i i j j j,用LCA找到他们的公共祖先 a n c anc anc,如果 d [ i ] [ a n c ] + d [ j ] [ a n s ] ≠ d [ i ] [ j ] d[i][anc]+d[j][ans]\ne d[i][j] d[i][anc]+d[j][ans]=d[i][j],则说明这幅图是错的,输出 N O NO NO。都没问题输出 Y E S YES YES

代码

// Good Good Study, Day Day AC.
#include <iostream>
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <cstring>
#include <math.h>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <map>
#include <algorithm> 
#include <unordered_map>
#include <unordered_set>
#define ffor(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define rrep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(v,s) memset(v,s,sizeof(v))
#define IOS ios::sync_with_stdio(false),cin.tie(0)
#define ll long long
#define INF 0x7f7f7f7f7f7f7f7f
#define inf 0x7f7f7f7f
#define PII pair<int,int>
#define int long long

using namespace std;

const int N = 2005;
int n, T;
int d[N][N];
int pi, p[N], nxt[N * 4], to[N * 4], cost[N * 4];
int minn[N];
int father[N];

int get_father(int root) {
	return father[root] == root ? root : father[root] = get_father(father[root]);
}

inline void add_in(int u,int v,int c)
{
	pi++; nxt[pi] = p[u]; p[u] = pi; to[pi] = v; cost[pi] = c;
}

struct Edge {
	int u, v, c;
}e[N*N];
int ei;

bool cmp(Edge i, Edge j) {
	return i.c < j.c;
}

void ready()
{
	IOS;
	cin >> n;
	ffor(i, 1, n) ffor(j, 1, n) cin >> d[i][j];
	ffor(i, 1, n) minn[i] = INF;
	ffor(i, 1, n) {
		ffor(j, i + 1, n) {
			e[++ei] = { i,j,d[i][j] };
		}
	}
	sort(e + 1, e + ei + 1, cmp);
	ffor(i, 1, n) father[i] = i;
	int cnt = 0;
	ffor(i, 1, ei) {
		int fu = get_father(e[i].u), fv = get_father(e[i].v);
		if (fu != fv) {
			cnt++;
			father[fu] = fv;
			add_in(e[i].u, e[i].v, e[i].c);
			add_in(e[i].v, e[i].u, e[i].c);
		}
		if (cnt == n - 1) break;
	}
}

int fa[N][15];
int depth[N];

void bfs()
{
	mst(depth, inf);
	depth[1] = 1; depth[0] = 0;
	queue<int> q;
	q.push(1);
	while (q.size()) {
		int u = q.front(); q.pop();
		for (int k = p[u]; k; k = nxt[k]) {
			int v = to[k];
			if (depth[v] > depth[u] + 1) {
				depth[v] = depth[u] + 1;
				q.push(v);
				fa[v][0] = u;
				ffor(i, 1, 12) {
					fa[v][i] = fa[fa[v][i - 1]][i - 1];
				}
			}
		}
	}
}

int lca(int x, int y)
{
	if (depth[x] < depth[y]) swap(x, y);
	rrep(i, 12, 0) {
		if (depth[fa[x][i]] >= depth[y]) {
			x = fa[x][i];
		}
	}
	if (x == y) return x;
	rrep(i, 12, 0) {
		if (fa[x][i] != fa[y][i]) {
			x = fa[x][i];
			y = fa[y][i];
		}
	}
	return fa[x][0];
}

bool dfs(int id,int u, int las,int dis) {
	if (d[id][u] != dis) return false;
	for (int k = p[u]; k; k = nxt[k]) {
		int v = to[k], c = cost[k];
		if (v == las) continue;
		if (!dfs(id, v, u, dis + c))
			return false;
	}
	return true;
}

bool work()
{
	ffor(i, 1, n) if (d[i][i]) return false;
	ffor(i, 1, n) ffor(j, 1, n) if (d[i][j] != d[j][i]) return false;
	ffor(i, 1, n) ffor(j, 1, n) if (i != j && d[i][j] == 0) return false;
	//bfs();
	ffor(i, 1, n) {
		if (!dfs(i,i,0,0)) {
			return false;
		}
	}
	return true;
}

signed main()
{
	ready();
	if (work())
		cout << "YES";
	else
		cout << "NO";
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值