ABC 320 A-E

目录

 A. Leyland Number

传送门:Leyland Number

tag:签到

题解:

B. Longest Palindrome

传送门:Longest Palindrome

tag:双指针,暴力

题解:

C.Slot Strategy 2 (Easy)

传送门:Slot Strategy 2 (Easy)

tag:暴力

复杂 and WA 思路

题解:

 D. Relative Position

传送门:Relative Position

tag:搜索

题解:

E. Somen Nagashi

传送门:Somen Nagashi

tag:优先队列

思考过程:

题解:


 A. Leyland Number

传送门:Leyland Number

tag:签到

题解:

数据范围小直接pow解决

B. Longest Palindrome

传送门:Longest Palindrome

tag:双指针,暴力

题解:

要寻找最长的回文字符串,我们外层循环就按长度从大到小遍历,内层循环回文字符串的起始位置,在内层循环里面再加一个双指针判断是否为回文字符串。

#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef double db;
const int N = 1e5 + 5, M = 1e9 + 7;
void solve()
{
    string s;
    cin >> s;
    int n = s.size();
    for (int l = n; n > 1; l--)
    {
        for (int i = 0; i <= n - l; i++)
        {
            bool f = true;
            int ll = i, rr = i + l - 1;
            while (ll < rr)
            {
                if (s[ll] != s[rr])
                {
                    f = false;
                    break;
                }
                ll++, rr--;
            }
            if (f)
            {
                cout << l << endl;
                return;
            }
        }
    }
    cout << 1 << endl;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t = 1;
    // cin>>t;
    while (t--)
        solve();
    return 0;
}

C.Slot Strategy 2 (Easy)

传送门:Slot Strategy 2 (Easy)

tag:暴力

复杂 and WA 思路

首先暴力方向是没有错的,我用的也是三重循环,但是我第一层写的是最终停止下来可能得到的数字,第二层是循环三个字符串,第三层是循环每一个字符串的每一个位置,如果这个位置没有被用过,就直接输出该位置,如果这个位置被用过,就保存一下用过的次数乘总长度。这个方法有一个弊端,就是如果前面的字符串有两个满足的,后面的字符串只有一个满足,且后面那个字符串满足的位置是前面的字符串中第一个满足的位置,那么就会导致答案不正确。

题解:

注意到了数据是100以内,但是思路想复杂了,半小时写了一堆代码和注释也没过,后面看了一眼别人的码,发现只用搞个三重循环就可以了,我考虑到了最多三次,但是我没有想到把字符串叠加在一起挨着,这样的话直接O(n^3)也能过。

#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
#define int long long
int a[3][110];
void solve()
{
	int n;
	cin>>n;
	string s[3];
	for(int i=0;i<3;i++) cin>>s[i];
	int ans = 3*n;
	for(int i=0;i<n*3;i++)
	{
		for(int j=0;j<n*3;j++)
		{
			for(int k=0;k<n*3;k++)
			{
				if(i == j || j == k || i == k) continue;
				if(s[0][i%n] == s[1][j%n] && s[0][i%n] == s[2][k%n])
				{
					ans = min(ans,max({i,j,k}));
				}
			}
		}
	}
	if(ans == 3*n) cout<<"-1"<<endl;
	else cout<<ans<<endl;
}
signed main()
{
	ios::sync_with_stdio(false);cin.tie(nullptr);
	int t=1;
	//cin>>t;
	while(t--)
	solve();
return 0;
}

 D. Relative Position

传送门:Relative Position

tag:搜索

题解:

这题乍一看没什么思路,但只要观察到这个题需要从第一个点出发,找到其他点的坐标,所以也不难想出这可以看成一个连通图的搜索,因为只有第一个点是知道的,所以我们只要从第一个点出发,搜索一遍即可。注意:需要保存为无向图,我们就用vector存储方向,再考虑输入的数据也要存双向,所以我们用一个map来存点A到B的差值和点B到A的差值。

#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef double db;
const int N = 2e5 + 5, M = 1e9 + 7;
vector<int> p[N];               //存储无向图
vector<bool> f(N);              //是否走过
vector<int> ans_x(N), ans_y(N); //保存答案
map<pair<int, int>, pair<int, int>> mp;
void bfs(int x)
{
    queue<int> q;
    q.push(x);
    f[x] = true;
    while (q.size())
    {
        x = q.front();
        q.pop();
        for (auto y : p[x])
        {
            if (f[y])
                continue;
            ans_x[y] = ans_x[x] + mp[{x, y}].first;
            ans_y[y] = ans_y[x] + mp[{x, y}].second;
            f[y] = true;
            q.push(y);
        }
    }
}
void solve()
{
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        int A, B, X, Y;
        cin >> A >> B >> X >> Y;
        p[A].push_back(B);
        p[B].push_back(A);
        mp[{A, B}] = {X, Y};
        mp[{B, A}] = {-X, -Y};
    }
    bfs(1);
    for (int i = 1; i <= n; i++)
    {
        if (f[i])
        {
            cout << ans_x[i] << " " << ans_y[i] << endl;
        }
        else
        {
            cout << "undecidable" << endl;
        }
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t = 1;
    // cin>>t;
    while (t--)
        solve();
    return 0;
}

E. Somen Nagashi

传送门:Somen Nagashi

tag:优先队列

思考过程:

每次排在前面的先出来拿面条,拿完之后给定冷却,等待冷却完毕再归队,为了省事本来想的是直接建立一个优先队列即可,将其放入其中,因为时间长的会沉在下面,但是wa了,没找到错误,再读了一遍题目,发现他是返回原位置,意思就是假设他是第一个人,如果他回到队伍了,那么他还是排在第一位,所以是他先拿面条,就算后面一直有人在等着,也是他先拿。因此我们需要开两个,一个是在队伍外面等待冷却的,另一个是等着拿面条的即可。注:此处优先队列需要开pair

题解:

每次取出在队伍最前面的人,并且给他面条和冷却,冷却完毕就归队继续拿面条,所以我们直接开两个优先队列,一个用来放置还在冷却期的人,一个用来放可以拿面条的人,冷却队列中需要将冷却时间做为第一键值,位置做为第二键值,另一个队列则相反,然后直接模拟一遍就行。

#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef double db;
const int N = 1e5 + 5, M = 1e9 + 7;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q, used;
void solve()
{
    int n, m;
    cin >> n >> m;
    vector<int> ans(n + 1);
    for (int i = 1; i <= n; i++)
    {
        q.push({i, 0});
    }
    int now = n;
    for (int i = 0; i < m; i++)
    {
        int t, w, s;
        cin >> t >> w >> s;
        while (used.size())
        {
            if (used.top().first <= t)
            {
                q.push({used.top().second, used.top().first});
                used.pop();
            }
            else
            {
                break;
            }
        }
        if (q.size() && q.top().second <= t)
        {
            auto it = q.top();
            q.pop();
            ans[it.first] += w;
            used.push({t + s, it.first});
        }
    }
    for (int i = 1; i <= n; i++)
    {
        cout << ans[i] << endl;
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t = 1;
    // cin>>t;
    while (t--)
        solve();
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nov-JovR

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值