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

2025ICPC陕西省赛题解

L. easy

每行选能选的最小的两个,注意处理奇数的情况。

#include <bits/stdc++.h>
#define x first
#define y second
#define int long longusing namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<long double,long double> PDD ;
const int N = 200010 , M = N * 2 , mod = 998244353 ;
int n ;
int a[1010][1010] ;void solve()
{cin >> n ;int c = 1 ;for(int i = 1 ; i <= n ; i ++)for(int j = 1 ; j <= n ; j ++)a[i][j] = c ++ ;int res = 0 ;for(int i = 1 ; i <= n ; i ++) {int u = (i + 1) / 2 ;u = 2 * (u - 1) + 1 ;res += a[i][u] + a[i][u + 1] ;}if(n % 2) res += n * n ;cout << res << "\n" ;
}
signed main()
{std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;int t = 1 ;
//    cin >> t ;while (t --) solve() ;return 0;
}
C. gcd

其实这道题就是在问,能不能找到b的一个因数,并且不是a的因数,我们每次用b除以a,b的最大公因数即可。

#include <bits/stdc++.h>
#define x first
#define y second
#define int long longusing namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<long double,long double> PDD ;
const int N = 200010 , M = N * 2 , mod = 998244353 ;void solve()
{int a , b ;cin >> a >> b ;if(a == b || b == 1) cout << "-1\n" ;else {int d = gcd(a , b) ;if(d == 1) {cout << b << "\n" ;return;}int u = b ;while (u % d == 0) {u /= d ;d = gcd(a , u) ;if(d == 1) break;}if(gcd(a , u) == 1 && gcd(b , u) != 1) cout << u << "\n" ;else cout << "-1\n" ;}
}
signed main()
{std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;int t = 1 ;cin >> t ;while (t --) solve() ;return 0;
}
G. student

题意就是说一个人如果两边分别有大于等于和小于等于他分数的人就可以出队。
假设a[mx]是最大值的位置,a[mn]是最小值的位置,那么(mx,mn)中的人一定可以全部走掉,(1,mx)之间大于大于a[1]的一定可以走掉,(1,mn)之间小于等于a[1]的一定可以走掉,(mx,n)之间大于等于a[n]的一定可以走掉,(mn,n)之间小于等于a[n]的一定可以走掉。
也就是说我们只用考虑1,mn,mx,n,这四个位置即可,如果有最大值和最小值和两个端点重复的就又会少留下一个。注意特判n=1的情况。

#include <bits/stdc++.h>
#define x first
#define y second
#define int long longusing namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<long double,long double> PDD ;
const int N = 200010 , M = N * 2 , mod = 998244353 ;
int n ;
int a[N] ;void solve()
{cin >> n ;for(int i = 1 ; i <= n ; i ++)cin >> a[i] ;if(n <= 2) {cout << n << "\n" ;return;}int res = 4 ;int mx = 0 , mn = 1e9 ;for(int i = 1 ; i <= n ; i ++)mx = max(mx , a[i]) , mn = min(mn , a[i]) ;if(mx == a[1] || mx == a[n]) res -- ;if(mn == a[1] || mn == a[n]) res -- ;cout << res << "\n" ;
}
signed main()
{std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;int t = 1 ;
//    cin >> t ;while (t --) solve() ;return 0;
}
J. Win

贪心,依次找出需要补充1个、2个、3个字母的数量。

#include <bits/stdc++.h>
#define x first
#define y second
#define int long longusing namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<long double,long double> PDD ;
const int N = 200010 , M = N * 2 , mod = 998244353 ;
int k ;
string s ;void solve()
{cin >> k >> s ;int res = 0 ;map<int,int> mp ;for(int i = 0 ; i < s.size() ; i ++) {string t = "" ;if(i + 3 < s.size()) {t = s.substr(i , 4) ;if(t == "lose") {mp[4] ++ ;i += 3 ;continue;}}if(i + 2 < s.size()) {t = s.substr(i , 3) ;if(t == "los" || t == "ose" || t == "lse" || t == "loe") {mp[3] ++ ;i += 2 ;continue;}}if(i + 1 < s.size()) {t = s.substr(i , 2) ;if(t == "lo" || t == "os" || t == "se" || t == "ls" || t == "le" || t == "oe") {mp[2] ++ ;i += 1 ;continue;}}if(s[i] == 'l' || s[i] == 'o' || s[i] == 's' || s[i] == 'e') {mp[1] ++ ;}}res = mp[4] ;for(int i = 3 ; i >= 1 ; i --) {int u = min(mp[i] , k / (4 - i)) ;res += u ;k -= (4 - i) * u ;}res += k / 4 ;cout << res << "\n" ;
}
signed main()
{std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;int t = 1 ;
//    cin >> t ;while (t --) solve() ;return 0;
}
A. Color

贪心题。我们可以假设对于每一种我们直接w[i]+n,把全部涂成一个颜色。这是发现如果对于连续的一段长度大于w[i]的全为颜色i的段,不涂色就好,也就是代价减少(这一段长度与w[i]的差值)。注意如果开头和结尾就是颜色i这一段可以不涂。

#include <bits/stdc++.h>
#define x first
#define y second
#define int long longusing namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<long double,long double> PDD ;
const int N = 200010 , M = N * 2 , mod = 998244353 ;
int n ;
int a[N] , b[N] ;void solve()
{cin >> n ;for(int i = 1 ; i <= n ; i ++) cin >> a[i] ;for(int i = 1 ; i <= n ; i ++) cin >> b[i] ;vector<int> p[n + 3] ;int u = 1 ;for(int i = 2 ; i <= n ; i ++)if(a[i] == a[i - 1]) u ++ ;else {p[a[i - 1]].push_back(u) ;u = 1 ;}p[a[n]].push_back(u) ;for(int i = 1 ; i <= n ; i ++) {int l = 1 , r = n ;while (a[l] == i) l ++ ;while (a[r] == i) r -- ;int sum = b[i] + r - l + 1 ;if(p[i].size()) {sort(p[i].begin() , p[i].end()) ;for(int j = p[i].size() - 1 ; j >= 0 ; j --) {if(p[i][j] > b[i]) sum -= p[i][j] - b[i] ;else break;}}cout << sum << " " ;}cout << "\n" ;
}
signed main()
{std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;int t = 1 ;
//    cin >> t ;while (t --) solve() ;return 0;
}
K. Welfare

贪心思维题,很多种情况,需要考虑的比较多。
可以看代码理解,这里提供两个容易错的样例。
4 1 7 2答案是15,3 2 10 2答案是16

#include <bits/stdc++.h>
#define x first
#define y second
#define int long longusing namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<long double,long double> PDD ;
const int N = 200010 , M = N * 2 , mod = 998244353 ;
int n , m , x , y ;void solve()
{cin >> n >> m >> x >> y ;if(n == 0 && m == 0) {cout << "0\n" ;return;}if(y == 0) {cout << x << "\n" ;return;}if(x == 0) {cout << (n + m) * y << "\n" ;return;}if(n > 0) {if(m == 0) {if(x > y) cout << x + (n - 1) * y << "\n" ;else cout << n * y << "\n" ;return;}if(x <= y) cout << y * (n + m) << "\n" ;else {if((n + 1) * y < x) cout << x + n * y << "\n" ;else {int l = 1 , r = n ;while (l < r) {int mid = (l + r) / 2 ;if(mid * y >= x) r = mid ;else l = mid + 1 ;}if(l * y >= x) l -- ;cout << max(x + n * y , x + (n + m - l) * y) << "\n" ;}}}else {if(x > y) cout << x << "\n" ;else cout << y * m << "\n" ;}
}
signed main()
{std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;int t = 1 ;cin >> t ;while (t --) solve() ;return 0;
}

该下班了,剩下的明天再补。


D Stock

当看到 n ≤ 30 n \leq 30 n30时就可以想到这道题需要dfs来做了。不管对于加法还是乘法,优先处理大数才能获得最优解法,所以先排序再dfs即可。(ps:一开始用long double 一直tle换成double就ac了)。

#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
//#define double long doubleusing namespace std;
typedef unsigned long long ULL ;
typedef pair<int,int> PII ;
typedef pair<double,double> PDD ;
const int N = 200010 , M = N * 2 , mod = 998244353 ;
int n ;
double u , res ;
vector<double> a , b ;void dfs(int i , int j , double x , double sum) {if(i == a.size() && j == b.size()) {res = max(res , sum) ;return;}if(i < a.size()) dfs(i + 1 , j , x + a[i] , sum + x + a[i]) ;if(j < b.size()) dfs(i , j + 1 , x * b[j] , sum + x * b[j]) ;
}
void solve()
{cin >> n >> u ;for(int i = 0 ; i < n ; i ++) {char c ;double x ;cin >> c >> x ;if(c == '+') a.push_back(x) ;else b.push_back(x) ;}sort(a.begin() , a.end()) , sort(b.begin() , b.end()) ;reverse(a.begin() , a.end()) , reverse(b.begin() , b.end()) ;dfs(0 , 0 , u , 0) ;res = res / (double)(n * 1.0) ;cout << fixed << setprecision(12) << res << "\n";
}
signed main()
{std::ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0) ;int t = 1 ;
//    cin >> t ;while (t --) solve() ;return 0;
}
http://www.xdnf.cn/news/473707.html

相关文章:

  • 以项目的方式学QT开发C++(一)——超详细讲解(120000多字详细讲解,涵盖qt大量知识)逐步更新!
  • 表记录的检索
  • 强化学习入门:马尔科夫奖励过程
  • 小白学编程之——数据库如何性能优化
  • c语言 写一个五子棋
  • 服务器选购指南:从零开始了解服务器
  • 【GitHub加速地址】
  • 比亚迪跨界降维打击!将正式宣布跨界,进入两三轮电动车电池市场
  • vue插槽的实例详解
  • 缺乏需求优先级划分时,如何合理分配资源?
  • python-修改图片背景色
  • java分布式服务的高可用处理
  • 优化算法加速深度学习模型训练
  • 《棒球百科》市运会是什么级别的比赛·棒球1号位
  • 一种改进DEIM(CVPR2025)的简单示例
  • 前端学习:align-items 和 justify-content 概念和区别
  • 图片通过滑块小图切换大图放大镜效果显示
  • SDC命令详解:使用get_pins命令进行查询
  • Vue.js---避免无限递归循环 调度执行
  • Weblogic SSRF漏洞复现(CVE-2014-4210)【vulhub靶场】
  • 黑马Java基础笔记-11
  • 深度学习之用CelebA_Spoof数据集搭建一个活体检测-训练好的模型用MNN来推理
  • Turbo C++
  • 数据驱动下的具身智能进化范式
  • 专项智能练习(定义判断)
  • 学习笔记:黑马程序员JavaWeb开发教程(2025.4.4)
  • threejs 大场景优化方案(代码层)
  • pycharm中qthread中的run函数debug不上的问题
  • 深度学习中的提示词优化:梯度下降全解析
  • 钉钉数据与金蝶云星空的无缝集成解决方案