首页 > 其他分享 >Codeforces Round 957 (Div. 3)

Codeforces Round 957 (Div. 3)

时间:2024-07-12 09:53:18浏览次数:6  
标签:片段 ok int Codeforces 957 next rightmost 长度 Div

推荐个C++编程仓库模板
https://github.com/yxc-s/programming-template

A. Only Pluses

总结:为什么优先增加最小的数,它们的乘积会是最优的呢?可以这么理解,假如只有两个数a和b,b>a,那么a + 1,就增加一份b。如果b + 1,只能增加1份a。因为 b > a,所以增加小的数是最优的。

void solve(){
	vector<int> a;
	for (int i = 0; i < 3; ++i){
		int t;
		cin >> t;
		a.push_back(t);
	}
	for (int i = 0; i < 5; ++i){
		auto it = min_element(a.begin(), a.end());
		(*it) ++;
	}
	int res = 1;
	for (auto x : a){
		res *= x;
	}

	cout << res << endl;
}

B. Angry Monk

题意:有个长度n和k个片段,问k个片段拼接成n的最小操作次数。 操作1:合并两个片段(必须有一个片段长度为1), 操作2: 分解为两个片段(分解为长度为1和长度-1的两个片段)

思路:贪心思想,最长的片段作为基础片段,其他长度的片段都要经历分解+组合两种操作(除长度为1的片段外),直接计数即可。

总结:习惯了n作为数组长度了,这次输入的长度为k,还wa了,哎。

void solve(){
	int n, k;
	cin >> n >> k;

	long long ans = 0;
	int maxn = 0;
	vector<int> a(k);
	for (int i = 0; i < k; ++i){
		cin >> a[i];
		maxn = max(maxn, a[i]);
	}
	bool ok = true;
	for (int i = 0; i < k; ++i){
		if (a[i] == maxn && ok == true){
			ok = false;
		}
		else{
			ans += (a[i] - 1) + a[i];
		}
	}

	cout << ans << '\n';
}

C. Gorilla and Permutation

题意:构造一个长度为n的排列,使这个排列的sigma(f[i] - g[i]) 最大。
f[i] : 在1~i的所有数中,>=k的所有数的和
g[i] : 在1~i的所有数种, <= m的所有数的和

思路: 优先让满足f条件的数早出现(越大越早),让满足g条件的数晚出现(越小越早)。

void solve(){
	int n, m, k;
	cin >> n >> k >> m;

	for (int i = n; i >= m; --i){
		cout << i << ' ';
	}
	for (int i = m - 1; i > k; --i){
		cout << i << ' ';
	}
	for (int i = 1; i <= k; ++i){
		cout << i << " \n"[i == k];
	}
}

D. Test of Love
题意:给定一个长度为n的字符串(1~n),问能否从位置0移动到位置n + 1。字符串包含"L", "W", "C",还有数字k和m。m表示当前只有在0或者L上面,能向右跳跃的最大距离。k表示在移动过程中只能在W上k次。C是障碍,可以跳过,但是不能站上去。

思路:分情况讨论。 从右往左记录距离当前位置最近的L的位置,用next数组表示。维护一个变量rightmost,表示当前位置~rightmost之间的位置都可以去(初始时为m)。
case 1: 如果rightmost >= next[i], i = next[i], 更新rightmost。(跳到下一个L位置)
case 2: 如果当前在陆地上,从当前能跳的最右边的距离往左找,找到第一个W(能到达的最右边的water),如果k <= 0或者没找到W, 无解
case 3: 如果当前在水里(W),k <= 0或者下一个字母是C,无解。

总结:一眼感觉应该用dp,感觉应该是当前能到达,所需要的最小k。但是看了一下感觉k的范围有点大,不太好维护,可能是状态想错了。 回头需要补一下dp的思路。 然后赛时用的方法是穷举所有情况,其实在cf的题目中,很多题目都是这样的思路,考虑所有情况,都安排好,需要注意的就是要理解整个程序的过程,思考出所有可能的现象。

void solve(){
    int n, m, k;
    cin >> n >> m >> k;
    string s;
    cin >> s;

    s = ' ' + s;
    s += "L";

    vector<int> next(n + 2);
    next[n + 1] = n + 1;
    for (int i = n; i >= 0; --i){
        next[i] = next[i + 1];
        if (s[i + 1] == 'L'){
            next[i] = i + 1;
        }
    }

    int rightmost = m;
    bool in_water = false;
    for (int i = 0; i <= n; ){
        if (next[i] <= rightmost){
            i = next[i];
            rightmost = i + m;
            in_water = false;
        }
        else {
            if (in_water){
                if (s[i + 1] == 'C' || k <= 0){
                    cout << "NO\n";
                    return;
                }
                else{
                    i ++;
                    k --;
                    rightmost = i + 1;
                    in_water = true;
                }
                
            }
            else if (k > 0){
                bool ok = false;
                for (int j = i + m; j > i; --j){
                    if (s[j] == 'W'){
                        i = j;
                        in_water = true;
                        ok = true;
                        rightmost = i + 1;
                        k --;
                        break;
                    }
                }
                if (!ok){
                    cout << "NO\n";
                    return;
                }
            }
            else{
                cout << "NO\n";
                return;
            }
        }
    }

    cout << "YES\n";

}

上面写完还剩一个多小时,为了避免熬夜坐牢,直接睡觉去了。

E. Novice's Mistake

题意:给定一个n,求所有满足条件的a和b。 条件:n重复a次后去掉后面b位 == a * n - b

赛时思路:设n的位数为x,看了样例后发现n重复i次后(ni),满足a * x - b == i * x,对于一个固定的重复次数i,可以知道b = a * x - i * x。那么a * n - b == ni.substr(a - b) ==> a * n - a * x + i * x, 而i应该不会超过6,所以算的速度很快。 但是这么算有一个问题,就是n可能重复的不是整数次,比如10重复2.5次是10101,所以根据上面的思路,样例3没过去,晚点再重新补好了。

标签:片段,ok,int,Codeforces,957,next,rightmost,长度,Div
From: https://www.cnblogs.com/yxcblogs/p/18297621

相关文章

  • Codeforces Round #956 (Div. 2)题解
    A.ArrayDivisibility需要让满足$k\midj$的所有\(a_j\)的和整除k,只需要让每个\(a_j\)整除k就可以了,可以让\(a_j=j\)#include<bits/stdc++.h>usingnamespacestd;#defineintlonglong#defineendl'\n'typedefpair<int,int>pii;typedefunsignedlonglo......
  • CodeForces - 1986G1 & CodeForces - 1986G2
    经过基本观察,可得当点对\((i,j)\)合法时,有\(a_i|b_j,a_j|b_i\),其中\(a_i=i/gcd(p_i,i),b_i=p_i/gcd(p_i,i)\),证明显然。如何维护?考虑开\(mp_{x,y}\)表示\(x=a_i\),\(y|b_i\)的个数。对于点\(i\)点对个数即为\(\sum\limits_{d|b_i}mp_{d,a_i}\)时间复杂度为\(O(nlog......
  • CodeForces - 1984E
    题目大意每次在每个联通块中选一个点\(u\),删除这个点使得联通块分成若干个联通块,再从联通块中选点\(v\),在新树上连接\(u,v\),求新树叶节点的最大个数。分析易转化为求原树的最大独立集,设\(f_{u,0/1}\)为以1为根时不选/选\(u\)的最大独立集。显然有:\[dp_{u,0}=\sum\li......
  • 高考后第一次Codeforces Round 952 (Div. 4)
    ACreatingWords思路:拿一个容器交换两数值即可#include<bits/stdc++.h>usingnamespacestd;constintN=100001;chara[N],b[N];intmain(){intn;scanf("%d",&n);while(n--){scanf("%s%s",a,b);charjia......
  • 研0 冲刺算法竞赛 day14 P1957 口算练习题
    思路:分别考虑以运算符或数字开头,为运算符,直接读入后面两个数字;为数字,在读入一个数字即可代码:#include<iostream>#include<cstring>#include<cstdio>usingnamespacestd;intmain(){ intN; cin>>N; charc[10],str[55],f; while(N--) { cin>>c; int......
  • div3E. Beautiful Array
    目录E.BeautifulArray原题链接题目思路代码E.BeautifulArray原题链接题目思路代码//https://codeforces.com/contest/1986/problem/E#include<bits/stdc++.h>#definecaseT\intT;\cin>>T;\while(T--)usingnamespacestd;usingll=lo......
  • Codeforces Round 954(Div. 3)
    CodeforcesRound954(Div.3)目录CodeforcesRound954(Div.3)\(C\).UpdateQueries\(D\).MathematicalProblem\(E\).BeautifulArray方法一:贪心+滑动窗口方法二:DP\(C\).UpdateQueries对索引数组\(ind\)去重排序对字符串\(c\)排序顺序遍历索引数组,将\(s[ind[i]......
  • Codeforces Round 916 (Div. 3)
    A.ProblemsolvingLog签到题,对于给出的字符串,记录每个字母出现的次数,然后遍历一遍,如果对应的字母出现的次数大于它的位次,则说明该题被解出来了,最后输出解题数量即可点击查看代码#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<vector>#......
  • Codeforces Round 956 (Div. 2) 部分题解A~C
    A.ArrayDivisibility题目大意构造长度为n的数组,满足:所有j的aj之和可以被k整除,其中j是k的倍数,k的取值为1~n。思路构造序列1->n即可满足条件。代码实现voidsolve(){  lln;cin>>n;  for(inti=1;i<=n;i++)cout<<i<<"";  cout<<"\n"......
  • joi2022_yo2_c 国土分割 (Land Division) 题解
    国土分割(LandDivision)推销我的洛谷博客。题意给定一个\(n\timesm\)的矩阵\(a\),你需要选择在横向或纵向分割至少一次,使得每个分割出来的小矩阵的\(a_{i,j}\)之和相等。数据范围\(1\leqslantn,m\leqslant50\)。\(1\leqslanta_{i,j}\leqslant10^5\)。思......