2020牛客暑期多校训练营(第三场)

2020牛客暑期多校训练营(第三场)(2020.7.18)

开始堇业,把之前欠的债补上。

A、Clam and Fish

有鱼的情况拿饵,后来用饵去换一条鱼实际上就是一换一,没区别。所以有鱼肯定拿鱼。

没鱼的情况有饵肯定拿饵。但这么搞问题是如果全是饵的话就炸了。

所以就是看当前饵能不能把剩下的池子全钓上来鱼,能的话就直接钓鱼了,后面就不需要拿饵了。

这题还哇了好几次,气死我了。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e6 + 10;
static char opt[MAXN];
int main()
{
    int t; scanf("%d", &t);
    while (t--)
    {
        int len; scanf("%d", &len); vector <int> temp;
        scanf("%s", opt);
        int ans = 0;
        for (int i = 0; i < len; ++i)
            if (opt[i] == '2' || opt[i] == '3') ++ans;
            else temp.push_back(opt[i] - '0');
        int baits = 0, n = temp.size();
        for (int i = 0; i < n; ++i)
        {
            if (n - i - 1 <= baits)
            {
                ans += baits; break;
            }
            else
            {
                if (temp[i] == 0 && baits > 0) ++ans, --baits;
                else if (temp[i] == 1) ++baits;
            }
        }
        cout << ans << endl;
    }
    return 0;
}

B、Classical String Problem

搞个指针记录起始位置,往后往前跳即可。

注意负数。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e6 + 10;
int main()
{
    static char s[MAXN]; scanf("%s", s); getchar();
    int beginner = 0;
    int MOD = strlen(s);
    int Q; cin >> Q; getchar();
    for (int i = 1; i <= Q; ++i)
    {
        char opt; int num; scanf("%c%d", &opt, &num);
        getchar();
        if (opt == 'M')
            beginner = ((beginner + num) % MOD + MOD) % MOD;
        else
            printf("%c\n", s[(beginner + num - 1) % MOD]);
    }
    return 0;
}

C、Operation Love

灵感来源:浩大师。

看这题给的巴掌图的右下角两条边,一条长9,一条长8。而且没有其它边和这两条边长度相同。把这两条边拿出来叉积一下就好了。

代码写得有点麻烦。另外eps要开小一点。

#include <bits/stdc++.h>
using namespace std;
class Point
{
public:
    double x, y;
    Point() {x = y = 0;}
    Point(double a, double b) { x = a; y = b; }
};
const double eps = 1e-3;
int dcmp(double x)
{
    if (fabs(x) < eps) return 0;
    if (x > 0) return 1;
    return -1;
}
Point operator -(Point a, Point b)
{
    return Point(a.x - b.x, a.y - b.y);
}
double operator ^(Point a, Point b)
{
    return a.x * b.y - a.y * b.x;
}
double operator *(Point a, Point b)
{
    return a.x * b.x + a.y * b.y;
}
double abs(Point x)
{
    return sqrt(x * x);
}
bool operator ==(Point x, Point y)
{
    if (!dcmp(x.x - y.x) && !dcmp(x.y - y.y)) return 1;
    return 0;
}
bool operator !=(Point x, Point y)
{
    if (x == y) return 0;
    else return 1;
}
int main()
{
    int t; cin >> t;
    while (t--)
    {
        Point a[30];
        for (int i = 1; i <= 20; ++i)
        {
            Point x; scanf("%lf%lf", &x.x, &x.y);
            a[i] = x;
        }
        vector <Point> vec;
        for (int i = 1; i <= 20; ++i)
        {
            for (int j = 1; j < i; ++j)
            {
                if (i == j) continue;
                if (!dcmp(abs(a[i] - a[j]) - 8) || !dcmp(abs(a[i] - a[j]) - 9))
                {
                    vec.push_back(a[i]); vec.push_back(a[j]);
                }
            }
        }
        /*for (auto &i : vec)
        {
            cout << i.x << ' ' << i.y << endl;
        }*/
        vector <Point> temp; Point rec;
        for (int i = 0; i < vec.size(); ++i)
        {
            for (int j = 0; j < temp.size(); ++j)
                if (vec[i] == temp[j])
                    rec = vec[i];
            temp.push_back(vec[i]);
        }
        //cout << rec.x << ' ' << rec.y << endl;
        Point v1, v2;
        for (int i = 0; i < vec.size(); ++i)
            if (vec[i] != rec)
            {
                if (!dcmp(abs(vec[i] - rec) - 8)) v1 = vec[i] - rec;
                if (!dcmp(abs(vec[i] - rec) - 9)) v2 = vec[i] - rec;
            }
        //cout << v1.x << ' ' << v1.y << endl;
        //cout << v2.x << ' ' << v2.y << endl;
        if ((v1 ^ v2) > 0) cout << "right" << endl;
        else cout << "left" << endl;
    }
    return 0;
}

E、Two Matchings

这题我是真的不会。璇大师把这题转换成了另一个模型,然后dp出来了。具体怎么搞的我也不是很清楚。似乎是四个或者六个为一组dp。代码:璇大师

% 璇大师 %

#include <iostream> 
#include <cstdio> 
#include <fstream> 
#include <algorithm> 
#include <cmath> 
#include <deque> 
#include <vector> 
#include <queue> 
#include <string> 
#include <cstring> 
#include <map> 
#include <stack> 
#include <set> 
using namespace std;
typedef long long ll;
ll dp[200005];
int main()
{
	ll T; ll n;
	scanf("%lld", &T);
	while (T--)
	{
		scanf("%lld", &n);
		vector<ll>q(n); ll sum=0;
		for (int i =0; i <n; i++)
		{
			scanf("%lld", &q[i]);
		}
		sort(q.begin(), q.end());vector<ll>de; ll ans=0;
		for (int i = 1; i < n; i++)
		{
			int d = q[i] - q[i - 1];
			sum += d;
			if(i>=4&&i%2==0&&i<=n-4)de.push_back(d);
		}
		if (de.size() == 0) ans = 0;
		else if (de.size() == 1) ans = de[0];
		else
		{
				dp[0] = de[0];
				if (de.size() >= 2)dp[1] = max(de[0], de[1]);
				if (de.size() >= 3)dp[2] = max(de[1], de[0] + de[2]);
				for (int i = 3; i < de.size(); i++)
				{
					dp[i] = max(dp[i - 2], dp[i - 3]) + de[i];
				}
				
				ans = max(dp[de.size() - 1], dp[de.size() - 2]);
				
		}
		printf("%lld\n", 2 * sum - 2 *ans);
	}
}

L、Problem L is the Only Lovely Problem

乱搞。

#include <bits/stdc++.h> 
using namespace std;
typedef long long ll;
int main()
{
	string s; bool flag = true;
	cin >> s;
	if (s.length() < 6) flag = false;
	else
	{
		for (int i = 0; i < 6; i++)
		{
			if (s[i] <= 'Z' && s[i] >= 'A')
				s[i] += 'a' - 'A';
		}
		if (s.substr(0, 6) != "lovely")
			flag =false;
		if (flag) cout << "lovely";
		else cout << "ugly";
	}
}

赛后总结:

这场思维题其实比较多。比如A和E,CF上面很喜欢出这种题,内味太重。

关键就是贪心和这种要点转化的dp我不是很搞得来。这一部分需要加强。

另外这场很明显能看到我们队队员之间码风差别很大。像璇大师命名变量和数组喜欢用拼音,浩大师的括号不换行等等。魔鬼般的缩进、不用空格格式化和莫名其妙的回车也是普遍存在的问题。

关于码风的问题已经在改了,主要通过每周三题训练。但是似乎队里除了我并没有什么补的积极性(?

过两天还是得检讨一下每周三题效果。目的主要有两个,一是训练思维查漏补缺,二是尽量让队内码风统一。不过这几周看下来码风问题还是很严重,补题只补了思路没改码风。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值