本期封面原图 画师るかちか 舞台剧篇的阿夸确实帅 当时看漫画就惊艳到我了
虽然下午练了两场但还是太久没打 哐哐掉分了😭😭😭
Educational Codeforces Round 170 (Rated for Div. 2)
A. Two Screens
题意
两个屏幕都要显示字符串,每次操作可以多打一个字符或者用一个屏幕覆盖另一块上的内容,最小化操作次数
思路
跟下午ABC374的B题很像啊,加一个计算就行
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void solve()
{
string s, t;
cin >> s >> t;
int n = min(s.length(), t.length());
for (int i = 0; i < n; i++)
{
if (s[i] != t[i])
{
if(i==0)
{
printf("%d\n",s.length()+t.length());
return ;
}
printf("%d\n", s.length()-(i+1)+1+t.length()-(i+1)+1+i+1);
return ;
}
}
if (s.length() == t.length())
printf("%d\n",n+1);
else
printf("%d\n", s.length()-(n+1)+1+t.length()-(n+1)+1+n+1);
}
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}
B. Binomial Coefficients, Kind Of
题意
有人把求组合数的预处理函数打成了这样
for (int n = 0; n < N; n++) { // loop over n from 0 to N-1 (inclusive)
C[n][0] = 1;
C[n][n] = 1;
for (int k = 1; k < n; k++) // loop over k from 1 to n-1 (inclusive)
C[n][k] = C[n][k - 1] + C[n - 1][k - 1];
}
要你以更快的速度求这个错误的答案
思路
打表发现直接输出 2 k 2^k 2k即可,除了最后一个特判
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const ll mod=1e9+7;
ll qpow(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1)
{
res=res*a%mod;
}
a=a*a%mod;
b>>=1;
}
return res;
}
void solve()
{
ll t;
scanf("%lld",&t);
ll n[t+1],k[t+1];
for(ll i=1;i<=t;i++)
{
scanf("%lld",&n[i]);
}
for(ll i=1;i<=t;i++)
{
scanf("%lld",&k[i]);
}
for(int i=1;i<=t;i++)
{
ll N=n[i],K=k[i];
if(K==0 or K==N)
printf("1\n");
else
printf("%lld\n",qpow(2ll,K));
}
}
int main()
{
int T=1;
// scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}
C. New Game
题意
拿牌,除了第一张每次可以拿前一张牌相同的或数字比前一张大1的牌,最多有k种不同数字,最大化牌数
思路
贪心地想肯定每种牌要拿完,就需要开桶记录每个数字的出现次数,然后滑动窗口就行了
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const int N=2e5+5;
map<ll,ll> a;
ll b[N];
int n,k;
void solve()
{
scanf("%d%d",&n,&k);
a.clear();
for(int i=1;i<=n;i++)
{
ll x;
scanf("%lld",&x);
a[x]++;
b[i]=x;
}
sort(b+1,b+n+1);
ll len=unique(b+1,b+n+1)-b-1;
ll l=b[1],r=b[1];
ll sum=a[b[1]];
ll ans=sum;
for(int i=2;i<=len;i++)
{
if(b[i]-r==1)
{
if (b[i] - l < k)
{
r++;
sum += a[b[i]];
ans = max(ans, sum);
}
else
{
sum -= a[l];
l++;
r++;
sum += a[b[i]];
ans = max(ans, sum);
}
}
else
{
l=b[i];
r=b[i];
sum=a[b[i]];
ans=max(ans,sum);
}
}
printf("%lld\n",ans);
}
int main()
{
int T=1;
scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}
D. Attribute Checks
题意
打关卡,有的关卡给你一个可以自由分配的点数,有的关卡要求你的智力或力量达标可以获得一分,最大化你的最终得分
思路
我最讨厌的dp 下面有注释 不想说了
代码
#include <bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
int smart[5001],strength[5001];
int pointSum=0;
int dp[5001][5001];
//i和j分别代表当前智商和当前体力
int main()
{
int n,m;
scanf("%d%d",&n,&m);
memset(dp,0,sizeof(dp));
memset(smart,0,sizeof(smart));
memset(strength,0,sizeof(strength));
ll ans=0;
for(int i=1;i<=n+1;i++)
{
// printf("%d\n",i);
int x;
if(i<=n)
scanf("%d",&x);
else
x=0;
if(x>0)
{
smart[x]++;
continue;
}
else if(x<0)
{
strength[-x]++;
continue;
}
else
{
int delta=0;
//前缀和,维护加上多少个点可以多过多少道关卡
for(int j=0;j<=pointSum;j++)
{
delta+=smart[j];
dp[j][pointSum-j]+=delta;
}
delta=0;
for(int j=0;j<=pointSum;j++)
{
delta+=strength[j];
dp[pointSum-j][j]+=delta;
}
//更新dp
for(int j=0;j<=pointSum;j++)
{
dp[j+1][pointSum-j]=max(dp[j+1][pointSum-j],dp[j][pointSum-j]);
//假如这个点点给了智商
dp[j][pointSum-j+1]=max(dp[j][pointSum-j+1],dp[j][pointSum-j]);
//假如这个点点给了体力
ans=max(ans,(ll)(dp[j+1][pointSum-j]));
}
for(int j=0;j<=pointSum;j++)
{
dp[pointSum-j][j+1]=max(dp[pointSum-j][j+1],dp[pointSum-j][j]);
//假如这个点点给了体力
dp[pointSum-j+1][j]=max(dp[pointSum-j+1][j],dp[pointSum-j][j]);
//假如这个点点给了智商
ans=max(ans,(ll)(dp[pointSum-j][j+1]));
}
pointSum++;
//清空
for(int j=0;j<=5000;j++) smart[j]=strength[j]=0;
}
}
printf("%lld\n",ans);
return 0;
}