Codeforces Round #627 (Div. 3)
题库链接
https://codeforces.com/contest/1324
A. Yet Another Tetris Problem
俄罗斯方块,\(2 \times 1\)的方块,显然只有高度差是偶数时才能消除全部
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 201110;
const int M = 1e9+7;
int n,m,k,ok;
int a[maxn];
signed main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
int T;
cin>>T;
while(T--)
{
cin>>n;
for(int i = 1; i <= n; i++)
{
cin>>a[i];
}
sort(a+1,a+1+n);
ok = 1;
for(int i = 2; i <= n; i++)
{
if((a[i]-a[i-1])%2) ok = 0;
}
if(ok) puts("YES");
else puts("NO");
}
return 0;
}
B. Yet Another Palindrome Problem
显然两个相等的数中间还有数,那么一定符合条件,暴力枚举就行了
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define int long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 201110;
const int M = 1e9+7;
int n,m,k,ok;
int a[maxn];
signed main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
cin>>n;
for(int i = 1; i <= n; i++)
{
cin>>a[i];
}
ok = 0;
for(int i = 1; i <= n && !ok; i++)
{
for(int j = i+2; j <= n; j++)
{
if(a[i] == a[j]) ok = 1;
}
}
if(ok) puts("YES");
else puts("NO");
}
return 0;
}
C. Frog Jumps
有一段L,显然跳跃长度必须大于这一段的长度才能跳过去
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define int long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 201110;
const int M = 1e9+7;
int n,m,k,ok;
signed main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
int T;
cin>>T;
while(T--)
{
string s;
cin>>s;
n = s.size();
int ans = 0, i = 0,res = 0;
while(i < n)
{
if(s[i] == 'L')
{
res++;
}
else
{
ans = max(ans,res);
res = 0;
}
i++;
}
ans = max(ans,res);
cout<<ans+1<<endl;
}
return 0;
}
D. Pair of Topics
\(a_i + a_j > b_i + b_j\),移项,\((a_i - b_i) + (a_j - b_j) > 0\)
那么对于每个\(i\),我们只要找大于\((-(a_i-b_i))\)的\(j\)的个数就好了
排序之后二分,复杂度\(O(nlogn)\)
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define int long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 201110;
const int M = 1e9+7;
int n,m,k,ok;
int a[maxn];
signed main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
for(int i = 1; i <= n; i++)
{
cin>>a[i];
}
for(int i = 1,x; i <= n; i++)
{
cin>>x;
a[i] -= x;
}
sort(a+1,a+1+n);
int ans = 0;
for(int i = 1; i <= n; i++)
{
int pos = upper_bound(a+1+i,a+1+n,-a[i])-a;
ans += (n+1-pos);
}
cout<<ans<<endl;
return 0;
}
E. Sleeping Schedule
定义\(dp[i][j]\)表示第\(i\)次在第\(j\)小时睡觉,所达到的最大睡眠次数
复杂度\(O(n^2)\)
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 2110;
const int M = 1e9+7;
int n,h,l,r;
int dp[maxn][maxn];
int a[maxn];
signed main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>h>>l>>r;
for(int i = 1; i <= n; i++)
{
cin>>a[i];
}
mem(dp,-inf);dp[0][0] = 0;
for(int i = 1; i <= n; i++)
{
for(int j = 0; j < h; j++)
{
int k = (j+a[i])%h;
dp[i][k] = max(dp[i][k],dp[i-1][j]+(k >= l && k <= r));
k = (j+a[i]-1+h)%h;
dp[i][k] = max(dp[i][k],dp[i-1][j]+(k >= l && k <= r));
}
}
int ans = 0;
for(int i = 0; i <= h; i++)
{
ans = max(ans,dp[n][i]);
}
cout<<ans<<endl;
return 0;
}
F. Maximum White Subtree
先把无根树看成有根树,对于每个点,我们把答案分成两部分,以\(i\)为根的子树部分,和除去\(i\)的子树的剩余部分
以\(i\)为根的子树部分可以利用树型dp求解
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 401110;
const int M = 1e9+7;
int n,m,k,ok;
int head[maxn],to[maxn],Next[maxn],cnt = 2;
void add(int u,int v)
{
to[cnt] = v;Next[cnt] = head[u];head[u] = cnt;cnt++;
}
int a[maxn];
int f[maxn];
int h[maxn];
void dfs(int u,int pre)
{
if(a[u] == 1) f[u] = 1;
else f[u] = -1;
for(int i = head[u]; i ; i = Next[i])
{
int v = to[i];
if(v == pre) continue;
dfs(v,u);
f[u] += max(f[v],0); //选与不选
}
}
void dfs2(int u,int pre)
{
int sum = max(0,h[u]);
if(a[u]) sum++;
else sum--;
for(int i = head[u]; i ; i = Next[i])
{
int v = to[i];
if(v == pre) continue;
sum += max(f[v],0);
}
for(int i = head[u]; i ; i = Next[i])
{
int v = to[i];
if(v == pre) continue;
h[v] = max(0,sum-max(f[v],0));
}
for(int i = head[u]; i ; i = Next[i])
{
int v = to[i];
if(v == pre) continue;
dfs2(v,u);
}
}
signed main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
cin>>n;
for(int i = 1; i <= n; i++)
{
cin>>a[i];
}
for(int i = 1,x,y; i < n; i++)
{
cin>>x>>y;
add(x,y);add(y,x);
}
dfs(1,0);
dfs2(1,0);
for(int i = 1; i <= n; i++)
{
cout<<f[i]+h[i]<<' ';
}
return 0;
}