一起来做题~欢乐赛2(题解)

总算把这几周的考试忙完了,接下来要多搞得就是刷题了吧。
比赛链接:这里
A:很久之前写的题了,这个题目说的虽然是二分,但是和二分没有一点关系,反而是用差分来写的。比较简单的一道题,直接放代码了。

#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
const int INF=0x7f7f7f7f;
map<int,int>mp;
int main()
{
    int t,n;
    char ch;
    cin>>t;
    while(t--)
    {
        cin>>n>>ch;
        if(ch=='.')
        {
            mp[n]++;
            mp[n+1]--;
        }
        if(ch=='+')
        {
            mp[-INF]++;
            mp[n]--;
        }
        if(ch=='-')
        {
            mp[n+1]++;
            mp[INF]--;
        }
    }
    int ans=-INF;
    int k=0;
    for(auto x:mp)
    {
      k+=x.second;
      ans=max(ans,k);
    }
    cout<<ans<<endl;
}

B:18年提高组的题,算是个完全背包。我们可以得到一个结论(m,b)里的数全是(n,a)里的数,所以我们可以用完全背包来写这道题,如果a里面的数可以用比它小的数来表示,那么直接n–,最后就可以得到答案。

#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)

using namespace std;

const int maxn = 1e5 + 5;

int x[105];
int dp[25005];
int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int n;
        cin >> n;
        for (int i = 1; i <= n; i++)
        {
            cin >> x[i];
        }
        sort(x + 1, x + 1 + n);
        int ans = n;
        memset(dp, 0, sizeof dp);
        dp[0]=1;
        for (int i = 1; i <= n; i++)
        {
            if(dp[x[i]])
            {
                ans--;
                continue;
            }
            for (int j = x[i]; j <= x[n];j++)
            {
                dp[j] = dp[j] | dp[j - x[i]];
            }
        }
        cout << ans << endl;
    }
}

C:这题也是一个简单的dp,比较难的是空间压缩,这里就不提供代码了(我也是看的别人的)。

D:我们首先要让这个图连通,因为这样才能进行下面的操作,所以我们首先要让几个连通块联通。然后我们需要一个奇数环,我们可以通过这个奇数环来使原先走不到的奇数点走到(注意这是个无向图),这样的奇数环我们只需要一个即可了。这是我们就得到了答案,先判断这个图有几个联通块,然后再判断有无奇数环即可得到答案。

#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)

using namespace std;

const int maxn = 1e6 + 5;

struct node
{
	int to, next;
} e[maxn];
int head[maxn];
int vis[maxn];
int cnt = 0;
int f = 1;
void add(int u,int v)
{
	e[++cnt] = {v, head[u]};
	head[u] = cnt;
}
void dfs(int t,int u)
{
	vis[t] = vis[u] + 1;
	for (int i = head[t]; i;i=e[i].next)
	{
		int v = e[i].to;
		if(v==t)
			continue;
		if(vis[v])
		{
			if(!(abs(vis[v]-vis[t])&1))//判断奇数环
				f = 0;
			continue;
		}
		dfs(v, t);
	}
}
int main()
{
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= m;i++)
	{
		int u, v;
		cin >> u >> v;
		add(u, v);
		add(v, u);
	}
	int ans = 0;
	for (int i = 1; i <= n;i++)
	{
		if(vis[i])
			continue;
		ans++;
		dfs(i, 0);
	}
	cout << ans - 1 + f;
}

E:二分图最大匹配模板题,比如
1 3
2 2
1 2
三组数据,如果我们1选了第一组数据,那么我们3就没办法选了,所以这是我们想让1选择其他的组,这就是个二分图最大匹配过程,敲个板子即可过题。

#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)

using namespace std;

const int maxn = 1e6 + 5;

vector<int> q[maxn];
int match[maxn], vis[maxn];
int dfs(int t,int i)
{
	for(auto x:q[t])
	{
		if(vis[x]!=i)
		{
			vis[x] = i;
			if(!match[x]||dfs(match[x],i))
			{
				match[x] = t;
				return 1;
			}
		}
	}
	return 0;
}
int main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n;i++)
	{
		int l,r;
		cin >> l >> r;
		q[l].push_back(i);
		q[r].push_back(i);
	}
	for (int i = 1; i <= n;i++)
	{
		if(!dfs(i,i))
		{
			cout << i-1;
			return 0;
		}

	}
	cout << n;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值