Educational Codeforces Round 161 (Rated for Div. 2) A-C 题题解

Educational Codeforces Round 161 (Rated for Div. 2) A-C 题题解

A题 Tricky Template Problem - A - Codeforces

题目概述:给你三个长度相等的字符串 a , b , c a , b,c a,b,c,并告诉你长度为 n n n。你需要找出一个模板,使字符串 a , b a,b a,b 能与该模板相符,而字符串 c c c 不能与其完全相符,相符条件如下:

1.当模板里的一个位置的字母 t i t_i ti 为小写时,待匹配的字符串相应位置 s i s_i si 必须与其相同。

2.当模板里的一个位置的字母 t i t_i ti 为大写时,待匹配的字符串相应位置 s i s_i si 无论大小写,必须与其不同。(例如,如果模板中有字母 “A”,则不能在字符串的相应位置使用字母 “a”)

存在就输出YES,不存在就输出NO

题目类型:构造,字符串

要点注意:

1.我们只需知道这个 模板 t t t 存不存在,而不需要把这个 t t t 求出来。

2.根据题意和观察样例我们可以发现。(写法一)

​ (1)只要存在一个下标 i i i ,使得 a i = = b i a_i == b_i ai==bi a i ! = c i a_i != c_i ai!=ci 时,该模板就可以存在(模板在 t i t_i ti 处取小写的 a i a_i ai),

​ (2)只要存在一个下标 i i i ,使得 a i ! = b i ! = c i a_i != b_i != c_i ai!=bi!=ci 时,该模板就可以存在(模板在 t i t_i ti 处取大写的 c i c_i ci

3.(写法二)

​ 只要存在一个下标 i i i ,使得 a i ! = c i a_i != c_i ai!=ci b i ! = c i b_i != c_i bi!=ci 时,该模板就可以存在(模板在 t i t_i ti 处取大写的 c i c_i ci

//
// Created by Mrlaolu on 2024/1/17.
//
#include<bits/stdc++.h>

#define int long long
#define endl '\n'
using namespace std;
const int N = 1010;

void solve()
{
                                                          写法一
    int n;
    cin >> n;
    string a,b,c;
    cin >> a >> b >> c;
    int flag = 1;
    for(int i = 0;i < n;++i)
    {
      if(a[i] == b[i] && a[i] != c[i] || a[i] != b[i] && a[i] != c[i] && b[i] != c[i])
      {cout << "YES\n";flag = 0;break;}
    }
    if(flag){cout << "NO\n";}
/*                                                         写法二
    int n;
    cin >> n;
    string a,b,c;
    cin >> a >> b >> c;
    int flag = 1;
    for(int i = 0;i < n;++i)
    {
      if(a[i] != c[i] && b[i] != c[i] )
      {cout << "YES\n";flag = 0;break;}
    }
    if(flag){cout << "NO\n";}
*/
}
signed main()
{

  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int t = 1;
  cin >> t;
  while (t--) {
    solve();
  }
  return 0;
}

B题 Forming Triangles Problem - B - Codeforces

题目概述:给你n根木棍,注意!!!给你的每根木棍的数字是它的长度的 2 2 2 次方(如给你 3 3 3 则意味着这根木棍的长度为 8 8 8 ( 2 3 = 8 2^3 = 8 23=8) )。求出有多少个组合能使木棍能组成一个三角形。

题目类型:构造,前缀和

要点注意:

1.通过举例观察,我们可以发现:因为 2 i + 1 = 2 ∗ 2 i = 2 i + 2 i 2^{i+1} = 2 * 2 ^ i = 2 ^ i + 2 ^ i 2i+1=22i=2i+2i ,而第三条边只能小于两条边之和。所以要形成一个三角形,只能选取两个相同大小的边和一个小于等于前两个的边( a = b = 2 i , c < = 2 i a=b=2^i,c<=2^i a=b=2i,c<=2i),故可因此写出代码。

//
// Created by Mrlaolu on 2024/1/17.
//
#include<bits/stdc++.h>

#define int long long
#define endl '\n'
using namespace std;

const int N = 1010;

void solve()
{
    int n;
    int ans = 0;
    cin >> n;
    multiset<int>a;        //运用multiset的count函数,能快速知道一个值的个数(当然也可以用map)
    map<int,int>xiaoyu;    //前缀和思想,快速找出比 2^i 小的数的个数
    int min1 = INT_MAX;
    int max1 = 0;
    for(int i = 0;i < n;++i)
    {
      int temp;
      cin >> temp;
      a.insert(temp);
      xiaoyu[temp]++;
      max1 = max(temp,max1);
      min1 = min(temp,min1);
    }

    for(int i = min1 + 1;i <= max1;++i)
    {
      xiaoyu[i] += xiaoyu[i-1];
    }

    for(int i = min1;i <= max1;++i)
    {
      if(!a.count(i)){continue;}
      if(a.count(i) >= 3){ans += a.count(i) * (a.count(i) - 1) * (a.count(i) - 2) / 6;}   //当三条边相同的时候,拿出来特判
      if(a.count(i) >= 2){ans += a.count(i) * (a.count(i) - 1) * (xiaoyu[i] - a.count(i)) / 2;}   //组合数公式
    }
    cout << ans << endl;
}

signed main()
{

  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int t = 1;
  cin >> t;
  while (t--) {
    solve();
  }
  return 0;
}

C题 Closest Cities Problem - C - Codeforces

题目概述:先给你一串长为 n n n 的数组,分别代表着 a 1 , a 2 . . . a n a_1,a_2...a_n a1,a2...an a 1 a_1 a1 的长度,这些城市分布在一条直线上。当下面给你 m m m 个操作,要算出从 $x $ 到 y y y 所要的最少的钱。如果前往的城市的为当前所在城市最近的一个,则收一枚硬币,否则收相应距离的硬币。

题目类型:前缀和,贪心

要点注意:

1.因为是求出所需最少的钱,那肯定是一步步从 x x x 走到 y y y,看看每一步能不能遇到最近的城市,从而少花点钱(因为去往最近的只用一枚硬币)。

2.如果每一次操作都从 x x x 一点点算到 y y y 肯定是会TLE的(或许)。观察到从城市 1 1 1开始往后走钱是一点点叠加起来的(有递推式 b i = b i − 1 + 从 a i 到 a i − 1 的路费 ( 1 或者 a i − a i − 1 ) ,其中 b i 为从城市 1 到 i , 所需的路费 b_i = b_{i - 1} + 从a_i到a_{i-1}的路费(1 或者 a_i - a_{i - 1}),其中 b_i 为从城市1到i,所需的路费 bi=bi1+aiai1的路费(1或者aiai1),其中bi为从城市1i,所需的路费)。我们可以推广出公式( 从 x 到 y 的路费 = b x − b y 从x到y的路费 = b_x - b_y xy的路费=bxby)(当 x < y x < y x<y 时)。

3.我们也可以依据上面这条写出( c i = c i + 1 + 从 a i + 1 到 a i 的路费 ( 1 或者 a i + 1 − a i ) ,其中 c i 为从城市 n 到 i , 所需的路费 c_i = c_{i + 1} + 从a_{i+1}到a_i的路费(1 或者 a_{i+1}-a_i),其中 c_i 为从城市n到i,所需的路费 ci=ci+1+ai+1ai的路费(1或者ai+1ai),其中ci为从城市ni,所需的路费),从而推广出( 从 x 到 y 的路费 = c x − c y 从x到y的路费 = c_x - c_y xy的路费=cxcy)(当 x > y x > y x>y 时)。

//
// Created by Mrlaolu on 2024/1/17.
//
#include<bits/stdc++.h>

#define int long long
#define endl '\n'
using namespace std;

const int N = 1e5+2;

vector<int>a(N);
map<pair<int,int>,int>m;
vector<int>c(N);



void solve()
{
  int n;
  cin >> n;
  for(int i = 1;i <= n;++i)
    cin >> a[i];

  vector<int>toR(n+1);           //toR 即为要点中的 数组b
  vector<int>toL(n+1);           //toL 即为要点中的 数组c
  vector<int>c(n+1);             //用于存每个城市的最近城市,方便算toR和toL时调用

  c[1] = 2;
  c[n] = n - 1;
  for(int i = 2;i < n;++i)          //存每个城市的最近城市
  {
    c[i] = ((a[i] - a[i - 1]) < (a[i + 1] - a[i]) ? i - 1 : i + 1);
  }

  for(int i = 1;i < n;++i)
  {
    toR[i + 1] = toR[i] + (c[i] == i + 1 ? 1 : a[i+1] - a[i]);
  }

  for(int i = n;i > 1;--i)
  {
    toL[i - 1] = toL[i] + (c[i] == i - 1 ? 1 : a[i] - a[i - 1]);
  }


  int t;
  cin >> t;
  while(t--)                      
  {
    int q,w;
    cin >> q >> w;
    if(q > w)
    {cout << toL[w] - toL[q] << endl;}
    else
    {cout << toR[w] - toR[q] << endl;}
  }

}

signed main()
{

  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int t = 1;
  cin >> t;
  while (t--) {
    solve();
  }
  return 0;
}
  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值