2022河南联赛第(四)场:郑州轻工业大学 --- 复盘

A ZZULI — 并查集 + 思维

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 2000010;
int b[N], idx=0;
int cnt[10];
int last[10], pre[10];
int p[N];

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

void merge(int a,int b)
{
    int pa = find(a), pb = find(b);
    if(pa == pb) return ;
    p[pa] = pb;
    cnt[pb] += cnt[pa];
}

signed main()
{
	string str; cin >> str;
    for(int i = 0; i < str.size(); i ++)
    {
        if(str[i] == 'Z')b[++idx] = 1;
        if(str[i] == 'U')b[++idx] = 2;
        if(str[i] == 'L')b[++idx] = 3;
        if(str[i] == 'I')b[++idx] = 4;
    }
    
    for(int i = 1; i <= idx; i ++) cnt[b[i]] ++, last[b[i]] = i;
    
    for(int i = idx; i >= 1; i --) pre[b[i]] = i;
    for(int i = 1; i <= 4; i ++) p[i] = i;
    
    for(int i = 1; i <= 4; i ++)
        for(int j = i + 1; j <= 4; j ++)
            if(pre[i] < last[j])
                merge(i, j);

    int res = 0;
    for(int i = 1; i <= 4; i ++) if(p[i] == i) res = max(res, cnt[i]);
    cout << res << '\n';
}

B 大本营 — 几何题 + 并查集

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;
#define int long long
typedef pair<int, int> PII;
const int N = 2010;
bool st[N];
int fa[N];
struct Node
{
	int x, y, r;
}a[N];

struct Point
{
	int x, y;
};
vector<Point> points;
void init()
{
	for (int i = 1; i < 2005; i++)
		fa[i] = i;
}
int get(int x)
{
	return fa[x] == x ? x : fa[x] = get(fa[x]);
}
void merge(int x, int y)
{
	fa[get(y)] = get(x);
}

//判断点是否在闭合区域内
bool IsPointInPolygon(Point p)
{
	//vector<Point> points:表示闭合区域由这些点围成
	int minX = points[0].x;
	int maxX = points[0].x;
	int minY = points[0].y;
	int maxY = points[0].y;
	for (unsigned int i = 1; i < points.size(); i++)
	{
		Point q = points[i];
		minX = min(q.x, minX);
		maxX = max(q.x, maxX);
		minY = min(q.y, minY);
		maxY = max(q.y, maxY);
	}

	if (p.x < minX || p.x > maxX || p.y < minY || p.y > maxY)
	{
		return false;
	}

	bool inside = false;
	for (unsigned int i = 0, j = points.size() - 1; i < points.size(); j = i++)
	{
		if ((points[i].y > p.y) != (points[j].y > p.y) && p.x < (points[j].x - points[i].x) * (p.y - points[i].y) / (points[j].y - points[i].y) + points[i].x)
		{
			inside = !inside;
		}
	}

	return inside;
}

signed main()
{
	init();
	int n, x, y;
	scanf("%lld%lld%lld", &n, &x, &y);

	bool flag = false;
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld%lld%lld", &a[i].x, &a[i].y, &a[i].r);
		if (a[i].r < 0) a[i].r = -a[i].r;
		if ((a[i].x - x) * (a[i].x - x) + (a[i].y - y) * (a[i].y - y) <= a[i].r * a[i].r)
			flag = true;
	}

	if (flag)
	{
		puts("NO");
		return 0;
	}

	for (int i = 1; i <= n; i++)
	{
		for (int j = i + 1; j <= n; j++)
		{
			int sum = (a[i].x - a[j].x) * (a[i].x - a[j].x) + (a[i].y - a[j].y) * (a[i].y - a[j].y);

			if (sum <= (a[i].r + a[j].r) * (a[i].r + a[j].r))
			{
				if (get(i) != get(j))
					merge(i, j);
				else
				{
					st[get(i)] = 1;
				}
			}
		}
	}
	for (int i = 1; i <= n; i++)
		fa[i] = get(i);
	for (int i = 1; i <= n; i++)
	{
		if (st[i] == 1)
		{
			points.clear();
			for (int j = 1; j <= n; j++)
			{
				if (get(j) == i)
				{
					Point P;
					P.x = a[j].x;
					P.y = a[j].y;
					points.push_back(P);
				}
			}
			if (IsPointInPolygon({x, y}))
			{
				flag = true;
				break;
			}
		}
	}
	if (flag)puts("NO");
	else puts("YES");
}

C 最大公因数 — 签到

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 200010;
void solve()
{
    int l, r, x;
    cin >> l >> r >> x;
    for(int i = l / x; i <= r / x; i ++)
    {
        if(i * x < l || i * x > r) continue;
        for(int j = i + 1; j <= r / x; j ++)
        {
            if(__gcd(i, j) == 1)
            {
                cout << i * x << " " << j * x <<'\n';
                return ;            
            }
        }
    }
    cout << -1 << '\n';
}

signed main()
{
	int T; cin >> T;
    while(T --) solve();
}

D 大盗 — 01背包

#include <iostream>
#include <cstring>
#include <algorithm>
#include <bitset>
using namespace std;
#define int long long
const int N = 50010;
bitset<N> f;
int n, k;
signed main()
{
    cin >> n >> k;
    f[0] = 1;
    for(int i = 1; i <= n; i ++) 
    {
        int op, x; 
        cin >> op >> x;
        if(op == 1)
            f  |= f << x;
        else
        {
            int t = f[x], s = f.count();
            f.reset();
            if(t) f[x] = 1;
            if(s) f[0] = 1;
        }
    }
    
    for(int i = k; i >= 0; i --)
        if(f[i])
        {
            cout << i << '\n';
            break;
        }
    
}

E 睡大觉 — 签到

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int res = 0;
string s;
int year, month, day, n;
int h1, m1, s1;
int pre = 0;
int cnt = 0;
int mouths[13]={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int is_leap(int x)
{
    return (x % 4 == 0 && x % 100 != 0) || (x % 400 == 0);
}
signed main()
{
    getline(cin,s);
    year = stoi(s.substr(0,4));
    month = stoi(s.substr(5,2));
    day = stoi(s.substr(8,2));
    cin >> n;
    for(int i = 0; i < n; i ++)
    {
        cin >> s;
        h1 = stoi(s.substr(0,2));
        m1 = stoi(s.substr(3,2));
        s1 = stoi(s.substr(6,2));
        int sum = h1 * 3600 + m1 * 60 + s1;
        if(sum + cnt * 3600 * 24 <= pre)
        {
            if(is_leap(year)) mouths[2] = 29;
            else mouths[2] = 28;
            cnt ++;
            day ++;
            if(day > mouths[month]) month ++,day = 1;
            if(month>12) month = 1,year ++;
        }
        pre = sum + cnt * 3600 * 24;
        if((month % 2) == (day % 2)) res ++;
    }
    cout << res << '\n';
}

G 迷宫 ---- 双端队列广搜

#include<iostream>
#include<cstring>
#include<algorithm>
#include<deque>
using namespace std;
#define int long long
typedef pair<int, int> PII;
const int N = 2010;
int n,m;
char g[N][N];
int dist[N][N];
bool st[N][N];
deque<PII>q;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int bfs()
{
    memset(dist, 0x3f, sizeof dist);
    memset(st, 0, sizeof st);
    dist[1][1] = 0;
    q.push_front({1, 1});
    st[1][1] = true;
    while(q.size())
    {
        auto t = q.front();
        q.pop_front();
        int x = t.first,y = t.second;
        if(x == n && y == m) return dist[n][m];
		st[x][y] = true;
        for(int i = 0; i < 4; i ++)
        {
            int a = x + dx[i], b = y + dy[i];
            if(a <= 0 || a > n || b <= 0 || b > m || g[a][b] == '#')continue;
            if(st[a][b]) continue;
			int dis = (g[a][b]=='.') + dist[x][y];
            if(dis < dist[a][b])
            {
                dist[a][b] = dis;
                if(g[a][b] == '.') q.push_back({a,b});
                else q.push_front({a,b});
            }
        }
    }
    if(dist[n][m] > 1e7) return -1;
    else return dist[n][m];
}

signed main()
{
    
    cin >> n >> m;
    for(int i = 1; i <= n; i ++) scanf("%s",g[i] + 1);
    cout << bfs() << '\n';
}

I 密集 — 二分

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N = 200010;

int n,k;
pair<int,int> a[N];
bool check(int t)
{
    int sum = 0, maxv = 0;
    for(int i = 0; i < n; i ++)
    {
        int dis = a[i].first+a[i].second * t;
        if(maxv > dis) sum ++;
        maxv = max(maxv, dis);
    }
    return sum >= n - k;
}

signed main()
{
    cin >> n >> k;
	for(int i = 0; i < n; i ++) cin >> a[i].first;
    for(int i = 0; i < n; i ++) cin >> a[i].second;
    sort(a, a + n);
    int l = 0, r = 2e9;
    while(l < r)
    {
        int mid = l + r >> 1;
        if(check(mid)) r = mid;
        else l = mid + 1;
    }
    if(r == 2e9) cout << "Never!" << '\n';
    else cout << r << '\n';
}

J 苹方树 — LCA + 数学 + 树形dp

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define int long long
const int N = 200010;
vector<int> g[N];
int n;
int dep[N], state[N];
int f[N][22];
int w[1010], st[1010];
void dfs1(int u, int fa)
{
	f[u][0] = fa;
	for(auto v : g[u])
	{
		if(v == fa) continue;
		dep[v] = dep[u] + 1;
		dfs1(v, u);
	}
}

int lca(int x,int y)
{
    if(dep[x] < dep[y]) swap(x,y);
    int d = dep[x] - dep[y];
    for(int i = 18; i >= 0; i --)
        if(d & (1 << i)) x = f[x][i];
        
    if(x == y) return x;
    
    for(int i = 18; i >= 0; i --)
        if(f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
    return f[x][0]; 
}

void dfs2(int u, int fa)
{
	for(auto v : g[u])
	{
		if(v == fa) continue;
		dfs2(v, u);
		state[u] ^= state[v];
	}
}

signed main()
{
	cin >> n;
	for(int i = 1, u, v; i < n; i ++) 
	{
		cin >> u >> v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs1(1, 0);
	for(int i = 1; i <= 19; i ++)
		for(int j = 1; j <= n; j ++)
			f[j][i] = f[f[j][i - 1]][i - 1];
	int now = 0;
	for(int i = 2; i <= 100 ; i++)
	{
		if(!st[i])
		{ 
			w[i] = 1 << now;
			now ++;
			for(int j = i + i; j <= 100; j += i)
			{
				int t = j;
				while(t % i == 0) w[j] ^= w[i], t/= i;
				st[j] = 1;
			}
		}
	}
	
	int m; cin >> m;
	while(m --)
	{
		int x, y, z; cin >> x >> y >> z;
		state[x] ^= w[z];
		state[y] ^= w[z];
		state[lca(x, y)] ^= w[z];
	}
	dfs2(1, 0);
	
	int q; cin >> q;
	while(q --)
	{
		int x; cin >> x;
		if(!state[x]) cout << "YES" << '\n';
		else cout << "NO" << '\n';
	}
}

K 试稥 — 签到

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
#define int long long
int st[100];
int n, m;
map<int, int>mp;
vector<int>vec;
void solve()
{
    cin >> n >> m;
    vec.clear();
    for(int i = 1, x; i <= n; i ++)
    {
        cin >> x;
        if(x & m) m -= x, vec.push_back(i);
    }
    if(m)
    {
        cout << -1 << '\n';
        return ;
    }
    cout << vec.size() << '\n';
    for(auto x : vec) cout << x << ' ';
    cout << '\n';
}

signed main()
{
	int T; cin >> T;
    while(T --) solve();
}

L 固执 — 结论 + 构造

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200010;
int c[30];
signed main()
{
    int n; cin >> n;
    string s; cin >> s;
    int maxv = 0;
    char maxc;
    for(auto x : s)
    {
        c[x - 'a'] ++;
        if(c[x - 'a'] > maxv)
        {
            maxv = c[x - 'a'];
            maxc = x;
        }
    }
    
    if(maxv <= n / 2)
    {
        cout << "NO" << '\n';
        return 0;
    }
    
    string res = "";
    res += maxc;
    c[maxc - 'a'] --;
    
    for(char i = 'z'; i >= 'a'; i --)
    {
        while(c[i - 'a'] > 0)
        {
            if(c[maxc - 'a'] > 0) res += maxc, c[maxc - 'a'] --;
            if(c[i - 'a'] > 0) res += i, c[i - 'a'] --;
        }
    }
    reverse(res.begin(), res.end());
    cout << "YES" << '\n';
    cout << res << '\n';
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_WAWA鱼_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值