总算把这几周的考试忙完了,接下来要多搞得就是刷题了吧。
比赛链接:这里
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;
}