首页 > 其他分享 >The 2023 ICPC Asia Jinan Regional Contest

The 2023 ICPC Asia Jinan Regional Contest

时间:2024-04-26 10:11:18浏览次数:33  
标签:std ... Jinan Contest int Regional 括号 cdots include

目录

写在前面

比赛地址:https://codeforces.com/gym/104901

以下按个人向难度排序。

SUA 的题确实牛逼,把我这种只会套路的沙比狠狠腐乳了。

D

签到。

直接枚举 \([L, \min(R, L + 10)]\) 检查即可。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
//=============================================================
//=============================================================
LL check(LL x_) {
  LL ret = 0;
  while (x_) {
    ret = std::max(ret, x_ % 10);
    x_ /= 10;
  }
  return ret;
}
//=============================================================
int main() {
  //freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  int T; std::cin >> T;
  while (T --) {
    LL la, ra, lb, rb; std::cin >> la >> ra >> lb >> rb;
    LL L = la + lb, R = ra + rb, ans = 0;
    for (LL i = L; i <= std::min(L + 10, R); ++ i) {
      ans = std::max (check(i), ans);
    }
    std::cout << ans << "\n";
  }
  return 0;
}

I

构造。

一个显然的想法是每次找到最小的无序的数值,设其位置为 \(p\),将其调整到第一个无序的位置 \(q\)。显然有 \(q<p,q < a_q\) 且 \((q, p)\) 一定构成逆序对。

然而直接这样做会被形如 5 1 2 3 4 这样的数据卡掉,原因是仅能保证每次只有最小的无序的数值被调整到有序位置,操作次数上限为 \(O(n)\) 级别。

于是考虑优化一下上述过程,考虑能否至少一次排两个位置,发现仅需将寻找最小的无序的数值改成寻找 \(a_{q} - 1\) 即可保证每次使前缀 \([1, a_{q}]\) 变为有序的,至少新增 \([q, a_{q}]\) 中至少两个有序位置,操作次数上限变为 \(O(\left\lfloor\frac{n}{2}\right\rfloor)\) 级别。

数据范围小的一批随便实现。

Code by hjxddl

//Coded by hjxddl
#include<cstdio>
#include<iostream>
#include<algorithm> 
#include<iomanip>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
const int N=2e5+5;
int t,n,a[105],ans1[105],ans2[105];
int x,x1,y,y1;
bool check(){
	for(int i=1;i<=n;i++){
		if(a[i]!=i){
			x=a[i],x1=i;
			return 1;
		}
	}
	return 0;
}
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=1;i<=n;i++)
			cin>>a[i];
		int ans=0;
		while(check()){
			for(int i=x1;i<=n;i++)
				if(x>a[i])
					y1=i;
			ans1[++ans]=x1;
			ans2[ans]=y1;
			sort(a+x1,a+y1+1);
		}
		cout<<ans<<'\n';
		for(int i=1;i<=ans;i++)
			cout<<ans1[i]<<" "<<ans2[i]<<"\n";
	}
}

A

思维。

以下是赛时的杀软做法。

发现一个括号串存在二义性等价于存在四个位置 \(i, j, k, l\):

  • \(i, j, k, l\) 为同种括号。
  • \([i + 1, j - 1], [j + 1, k - 1], [k + 1, l - 1]\) 均可转化为合法括号串。

则可以将这四个位置进行如下转换:

\[(\cdots(\cdots)\cdots) \iff (\cdots)\cdots(\cdots) \]

保证给定的括号串一定存在一种合法构造,于是先考虑用栈按照最左优先匹配搞出一种来,则若存在满足上述条件的四个位置 \(i, j, k, l\),它们对应的区间一定被构造成了 \((\cdots)\cdots(\cdots)\) 的形式。

若位置 \(i\) 在构造方案中为右括号,则记位置 \(i\) 匹配的括号位置为 \(p_i\),考虑枚举每一对匹配的括号 \((p_i, i)\):

  • 检查 \((p_{p_i - 1}, i - 1)\) 是否存在,若存在检查其类型。若为同种则可构成 \((\cdots)(\cdots)\) 的形式说明有二义性。
  • 若不同种,检查 \((p_{p_{p_i - 1}}, p_{i - 1} - 1)\) 是否存在,若存在检查其类型。若与 \((p_i, i)\) 同种则可构成 \((\cdots)[\cdots](\cdots)\) 的形式说明有二义性;若不同种则可构成 \([\cdots][\cdots](\cdots)\) 的形式,这种情况同样有二义性,且一定会在枚举到 \((p_{p_{i} - 1}, p_{i} - 1)\) 的时候被检查到。

按照上述过程讨论即可。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
#define pii std::pair<int,int>
#define mp std::make_pair
const int kN = 1e6 + 10;
//=============================================================
std::map <char, int> type;
//=============================================================
//=============================================================
int main() {
  // freopen("1.txt", "r", stdin);
  std::ios::sync_with_stdio(0), std::cin.tie(0);
  type['('] = type[')'] = 0;
  type['['] = type[']'] = 1;


  int T; std::cin >> T;
  while (T --) {
    std::string s;
    int flag = 0;
    std::cin >> s;
    std::stack<int> st1, st2;
    std::map <int,int> m;
    m.clear();

    for (int i = 0, len = s.length(); i < len; ++ i) {
      int key = type[s[i]];
      if (st1.empty()) {
        st1.push(i), st2.push(key);
      } else if (key != st2.top()) {
        st1.push(i), st2.push(key);
      } else {
        m[i] = st1.top();
        m[m[i]] = i;
        st1.pop(), st2.pop();
      }
    }

    for (int i = 0, len = s.length(); i < len; ++ i) {
      int p = m[i];
      if (p > i) continue;

      if (p - 1 < 0) continue;
      int q = m[p - 1];
      if (q > p - 1) continue;
      if (type[s[p - 1]] == type[s[i]]) {
        flag = 1;
        break;
      }

      if (q - 1 < 0) continue;
      int l = m[q - 1];
      if (l > q - 1) continue;
      if (type[s[q - 1]] == type[s[i]]) {
        flag = 1;
        break;
      }
    }
    std::cout << (flag ? "No" : "Yes") << "\n";
  }
  return 0;
}

赛后看了题解妈的场上太暴力了。

手玩发现有唯一构造的括号串实际上均形如 ([([...])]) 这样两种括号交替嵌套,或者为两个外层括号不同的上述括号串 ([(...)])[([...])]

  • 若有两个外层括号相同的上述括号串,如 ([...])([...]) 显然有二义性。
  • 若有两个以上的上述括号串,如 ([...])[(...)]([...]) 显然可以构成上述 (...)...(...) 的二义性形式。

发现只要有相邻的两个位置 \(s_i, s_{i + 1}\) 为同种括号,说明出现了一个两种括号交替嵌套的子串(此类子串的最内层括号),或者有两个上述子串最外层括号相同。

于是仅需检查相邻的两个位置 \(s_i, s_{i + 1}\) 为同种括号的情况是否出现不大于 2 次即可。

G

图论转化,连通性问题,计数

挺典的套路呃呃,然而学艺不精场上恼弹只建了单倍节点的图导致传递性爆炸了一直 WA 呃呃太飞舞

写在最后

学到了什么:

  • I:考虑每次操作至少影响的位置口牙
  • A:大力手玩口瓜
  • G:命题为真假的依赖关系的图论转化口也

听忍术研究部角色歌上头了,咕,可爱至极口牙!

<iframe allowfullscreen="allowfullscreen" frameborder="0" height="500" sandbox="allow-top-navigation allow-same-origin allow-forms allow-scripts" scrolling="no" src="//player.bilibili.com/player.html?aid=1803319537&bvid=BV1Ft421j7gp&cid=1514945472&p=1" width="100%"> </iframe>

标签:std,...,Jinan,Contest,int,Regional,括号,cdots,include
From: https://www.cnblogs.com/luckyblock/p/18159367

相关文章

  • The 2022 ICPC Asia Xian Regional Contest / ICPC 西安 2022 (ABDHJKL)
    本文搬运自本人的知乎文章。https://zhuanlan.zhihu.com/p/588162564好久没有在补题之后写题解的习惯了。但是最近感觉有些题目的思路即使在题目通过后仍然难以理清,因此觉得需要写些东西帮助自己整理思路,另外也方便以后翻看积累到的技巧。J.StrangeSum题目链接Problem-J......
  • 2022 China Collegiate Programming Contest (CCPC) Mianyang | 2022 CCPC 绵阳(MAED
    搬运自本人知乎文章。https://zhuanlan.zhihu.com/p/588646549M.Rock-Paper-ScissorsPyramid题目链接Problem-M-Codeforces题意有一个长度为\(n\)的石头剪刀布序列,每个元素是RPS(石头、布、剪刀)中的一个,我们需要用这个序列构造一个三角,三角的底层为这个序列,第\(i(......
  • The 2022 ICPC Asia Xian Regional Contest
    The2022ICPCAsiaXianRegionalContestJ.StrangeSum题意:给定n个数,选定最多不超过两个数字的和的最大值思路:签到voidsolve(){lln;cin>>n;vector<ll>a(n+1);for(inti=1;i<=n;i++)cin>>a[i];llans=0;sort(a.begin()......
  • AtCoder Beginner Contest 350 A - G 题解
    AtCoderBeginnerContest350A-PastABCsSolution把最后三个字符转成数字判断即可Code#include<bits/stdc++.h>usingnamespacestd;intmain(){strings;cin>>s;s=s.substr(3,3);intx=0;x=(s[0]-'0')*100+(s[1]-�......
  • The 18-th Beihang University Collegiate Programming Contest (BCPC 2023) - Final
    https://codeforces.com/gym/104883A#include<bits/stdc++.h>usingnamespacestd;usingi32=int32_t;usingi64=longlong;usingvi=vector<int>;i32main(){ios::sync_with_stdio(false),cin.tie(nullptr);i64n,sum=0;c......
  • AtCoder Beginner Contest 350 G - Mediator
    链接:https://atcoder.jp/contests/abc350/tasks/abc350_g大致题意:给出n个点,q个询问1号询问要求u,v之前加一条无向边图始终是一个森林2号询问询问是否有一个点与u,v都相邻,若有则输出该点,若无则输出0。询问强制在线。思路:在题目要求的图中,满足2号询问的点只有三种情况:要么这个......
  • AtCoder Beginner Contest 350
    B-DentistAoki难度:⭐题目大意现在有数列1~n,现在有m次操作,每次给出一个x,如果x存在就是删去,不存在就加上;问最后数列还剩多少个;解题思路数据很小,暴力就行;神秘代码#include<bits/stdc++.h>#defineintlonglong#defineIOSios::sync_with_stdio......
  • AtCoder Beginner Contest 350
    A-PastABCs(abc350A)题目大意给定一个形如ABCXXX的字符串。问XXX是否是\(001\to349\)之间,且不能是\(316\)。解题思路将后三位转换成数字后判断即可。神奇的代码a=int(input().strip()[3:])ifa>=1anda<=349anda!=316:print("Yes")else:p......
  • AtCoder Beginner Contest 350 (小白来了)
    A-PastABCs思路:题意需要计算已经结束的比赛其中1~349属于已经结束的比赛,其中316没有计算进去模拟即可Code:#include<bits/stdc++.h>usingnamespacestd;intmain(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);strings;cin>......
  • AtCoder Beginner Contest 350 解题报告
    AtCoderBeginnerContest350A-PastABCs当且仅当串为\(\texttt{ABC000},\texttt{ABC316},\texttt{ABC350}\sim\texttt{ABC999}\)时输出\(\texttt{No}\)。(本人因\(000\)挂了一发。)#include<bits/stdc++.h>usingnamespacestd;intmain(){ ios::sync_with_......