当前位置: 首页 > news >正文

Educational Codeforces Round 170 (Rated for Div. 2)(A~E题解)

本场也算是对我努力的一个reward吧,也是非常nice啊,话不多说,先写题解,写完直接休息

A. Two Screens

思路:我们先去想其最多需要多少次,也就是两个串长度之和,然后在哪里有优化呢?就是说两个串之间有可能有相等的前缀,可以将前缀直接拓印过来,将相同长度k的的前缀串复制过来,将操作化简为1,直接用sum-k+1即可,当然了,有可能有相同的部分为0,如果为0,直接输出两个串长度之和

#include<bits/stdc++.h>
using namespace std;
#define int long longint q;
string s,t;
void solve()
{cin>>s>>t;int cnt=0;int sum=s.size()+t.size();for(int i=0;i<min(s.size(),t.size());i++){if(s[i]==t[i])cnt++;elsebreak;}if(cnt==0)cout<<sum<<"\n";elsecout<<sum-cnt+1<<"\n";
}
signed main()
{cin>>q;while(q--)solve();return 0;
}

B. Binomial Coefficients, Kind Of

思路:看题就是说求错误的最终结果,我们每次取的都是左边一个+左上一个

我们手玩一下就发现了规律,第k列的值就是2的k次方,直接用快速幂

#include<bits/stdc++.h>  
using namespace std;  
#define int long long  int t;  
const int mod = 1e9 + 7;  
int n[100005];  
int k[100005];  // 快速幂公式  
int fast(int a, int b)   
{  long long result = 1;  long long base = a % mod;  // 计算base时取mod,防止溢出  while (b > 0)   {  if (b % 2 == 1)   {  result = (result * base) % mod;  }  base = (base * base) % mod;  b /= 2;  }  return result;  
}  signed main()  
{  cin >> t;  for (int i = 1; i <= t; i++)  {  cin >> n[i];  }  for (int i = 1; i <= t; i++)  {  cin >> k[i];  }  for (int i = 1; i <= t; i++)  {  cout << fast(2, k[i]) << "\n";  }  return 0;  
}

 C. New Game

思路:我们首先需要用一个map去统计每个数出现的次数,然后快排一下,去重,跑一遍单调队列,我们在单调队列中去处理结果

我们用sum去表示过程中的值,ans表示最终的最大值

如果队列不为空并且当前要插入的元素和队尾元素差值不是1,那么去更新最大值,然后将sum变为0 

如果队列不为空,但是插入的值和第一个元素的值差值大于等于k,说明插入的元素要多于k了,因此我们需要将队首元素弹出,并且sum-队首元素的次数

#include<bits/stdc++.h>
using namespace std;int t;
int n, k;
int a[200005];
map<int, int> mp;
struct node
{int x;int cnt;
};
deque<node> que;
void solve()
{cin >> n >> k;mp.clear();for(int i = 1; i <= n; i++){cin >> a[i];mp[a[i]]++;}sort(a + 1, a + 1 + n);int len = unique(a + 1, a + 1 + n) - (a + 1);vector<node> q(len + 1);for(int i = 1; i <= len; i++){q[i].x = a[i];q[i].cnt = mp[a[i]];}int sum = 0;int ans = 0;for(int i = 1; i <= len; i++){if (!que.empty() && q[i].x - 1 != que.back().x){ans = max(ans, sum);sum = 0;while (!que.empty()){que.pop_back();}}while (!que.empty() && que.front().x<=q[i].x-k){ans = max(ans, sum);sum -= que.front().cnt;que.pop_front();}que.push_back(q[i]);sum += q[i].cnt;ans = max(ans, sum);}cout << ans << "\n";while (!que.empty()){que.pop_back();}
}signed main()
{ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin >> t;while (t--)solve();return 0;
}

D. Attribute Checks

思路:我们只需要去枚举每个0的位置,然后用dp[i]去表示前面加了i次智力的最大值,如果前面有cnt个0,那么就是加了cnt-i次力量,然后去统计每次属性之后的最值

#include<bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n,m;
int a[2000005];
int dp[2000005];
int zhi[2000005];
int wu[2000005];
void solve()
{cin>>n>>m;for(int i=1;i<=n;i++){cin>>a[i];}int cnt=0;for(int i=1;i<=n;i++){if(a[i]>0){zhi[a[i]]++;}if(a[i]<0){wu[-a[i]]++;}if((a[i]==0&&cnt<2*m)||i==n)  {  for (int j=1;j<=cnt;j++)  {zhi[j]+=zhi[j-1];wu[j]+=wu[j-1];  }for (int j=0;j<=cnt;j++)  {dp[j]+=zhi[j]+wu[cnt-j];}for (int j=cnt+1;j>0;j--)  {dp[j] = max(dp[j],dp[j-1]);  }cnt++;for (int j=1;j<=cnt;j++)  {zhi[j]=0;wu[j]=0;  }}  }int ans=0;for(int i=1;i<=cnt;i++){ans=max(ans,dp[i]);} cout<<ans<<"\n";return;
}
signed main()
{t=1;while(t--)solve();return 0;
}

E. Card Game

等白天来更新思路,太困了,不想码字了 

#include<bits/stdc++.h>  
using namespace std;  
#define int long long  
const int MAX = 1007, MOD = 998244353;  int dp[1007][1007];    
int fac[1007];        
int inv[1007];         int fastpow(int a, int b, int mod)   
{  int res = 1;  while (b)   {  if (b & 1) res = res * a % mod;a = a * a % mod; b >>= 1;}  return res;  
}  int calc(int n, int cnt)   
{  return (fac[2 * n - cnt] * inv[n - cnt] % MOD * inv[n] % MOD - fac[2 * n - cnt] * inv[n - cnt - 1] % MOD * inv[n + 1] % MOD + MOD) % MOD;  
}  void solve()   
{  int n, m;  cin >> n >> m;fac[0] = 1;  for (int i = 1; i < MAX; i++)  fac[i] = fac[i - 1] * i % MOD;  inv[MAX - 1] = fastpow(fac[MAX - 1], MOD - 2, MOD);  for (int i = MAX - 2; i >= 0; i--)  inv[i] = inv[i + 1] * (i + 1) % MOD;  for (int i = m; i >= 0; i -= 2)   {  dp[1][i] = calc((m + i) / 2, i);  }  for (int i = 2; i <= n; i++)   {  for (int j = 0; j <= m; j++)   {  for (int k = 0; k <= j; k++)   {  if ((j - k + m) % 2 == 0)  dp[i][k] = (dp[i][k] + dp[i - 1][j] * calc((j - k + m) / 2, j - k) % MOD) % MOD;  }  }  }  cout << dp[n][0] << '\n';  
}  signed main()   
{  ios_base::sync_with_stdio(false);  cin.tie(0);  cout.tie(0);  solve(); return 0;  
}


http://www.mrgr.cn/news/50291.html

相关文章:

  • 增强对象智能:谷歌开源的XR-Objects项目简介
  • Python | Leetcode Python题解之第480题滑动窗口中位数
  • UG(交互式CAD/CAM系统)-WINDOWS 11安装教程
  • 023 elasticsearch查询数据 高亮 分页 中文分词器 field的数据类型
  • 多模态大模型 + 数字人 实现半自动 演示文稿 PPT讲解 搭建赛博老师傅 助力程序员赛博飞升!!!
  • Java | Leetcode Java题解之第479题最大回文数乘积
  • SpringCloud学习记录|day5
  • torch.jit.script编译加速推理的尝试
  • 读书笔记《PPT演讲力》大树模型
  • 如何优化 Nginx 配置
  • 用Java写一个学生类
  • RA6M5——GPIO
  • React前端框架的描述和使用方法
  • Java开发中知识点整理
  • P1439 【模板】最长公共子序列 Python 题解
  • Redis如何批量删除指定前缀的key
  • 单点登录Apereo CAS 7.1客户端登出配置及免认证页面问题
  • 安装和配置Canal
  • Linux rm命令详解
  • 面对服务器掉包的时刻困扰,如何更好的解决