Daliy Algorithm (字符串,暴力,数学)-- day 96

Nothing to fear


种一棵树最好的时间是十年前,其次是现在!

那些你早出晚归付出的刻苦努力,你不想训练,当你觉的太累了但还是要咬牙坚持的时候,那就是在追逐梦想,不要在意终点有什么,要享受路途的过程,或许你不能成就梦想,但一定会有更伟大的事情随之而来。 mamba out~

2020.7.26


人一我十,人十我百,追逐青春的梦想,怀着自信的心,永不言弃!

CF#658Div2-C1

分析

首先观察数据范围大概是一个\(O(n^2)\)的时间复杂度,毕竟n只有1000

我们倒着考虑,因为每一次都是处理前缀,所以我们尽可能保证后面地都稳定下来。

由于我们每次都需要选择一个前缀并进行修改bit位同时进行逆转,所以逆转之前实际上我们需要观察当前字符串 a[0] 和 当前 b[i] 是否一致。如果一致地话那么逆转之后再进行flip地话就和原来一样没有起到平衡作用,故如果当前 a[0] != b[i]地话需要先单独修改第一位,即长度为 1 地前缀,否则直接进行颠倒 flip即可。

完整代码

#include <bits/stdc++.h>
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define lowbit(x) (x & -x)
using namespace std;
typedef long long ll;
const int MAX = 0x7ffffff;
int t;

// 最多需要3n步能够从a -> 转换到 b
// 每次颠倒需要选择一个前缀进行按位取反并且倒序
void slove()
{
	int n;cin >> n;
	string a , b;
	cin >> a >> b;
	vector<int> ops;
	for(int i = n - 1;i >= 0;i --)
	{
		if(a[i] != b[i])
		{
			if(a[0] == b[i])
			{
				ops.push_back(1);
				a[0] = '0' + !(a[0] - '0');
			}
			reverse(a.begin(),a.begin() + i + 1);
			for(int j = 0;j <= i;j ++)
			{
				a[j] = '0' + !(a[j] - '0');
			}
			ops.push_back(i + 1);
			cout << a << " " << b << endl;
		}
	}
	cout << ops.size() << " ";
	for(int x : ops)
	{
		cout << x << " ";
	}
	cout << endl;
}
int main()
{
#ifdef LOCAL
	auto start_time = clock();
	cerr << setprecision(3) << fixed; // 在iomanip中
#endif
	SIS;
	cin >> t;
	while(t--)
	{
		slove();
	}
#ifdef LOCAL
	auto end_time = clock();
	cerr << "Execution time: " << (end_time - start_time) * (int)1e3 / CLOCKS_PER_SEC << " ms\n";
#endif
}

#657Div2-A

我们遍历s中每一个长度为 t.size() 的子串

  1. 检查每一个取出的字串,如果出现了s[i + j] != '?' && s[i + j] != t[j]的话
    那么这个字串一定不合法可以直接中止检查该子串
  2. 如果检查完毕,并且该字符串中当前只有一个子串
    如果此时 s 中还存在 ? 那么可以直接将其标记为其余字母

如果得到合法的串输出
否则失败

#include <bits/stdc++.h>
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define lowbit(x) (x & -x)
using namespace std;
typedef long long ll;
const int MAX = 0x7ffffff;
int test;
string s , t = "abacaba";

int count(string s)
{
	int cnt = 0;
	for(int i = 0;i < (int)s.size();i ++)
	{
		if(s.substr(i , 7) == t)
			++cnt;
	}
	return cnt;
}
void slove()
{
	int n;	
	cin >> n >> s;
	bool F = false;
	for(int i = 0;i + t.size() <= n;i ++)
	{
		string ss = s;bool ok = true;
		for(int j = 0;j < t.size();j ++)
		{
			if(ss[i + j] != '?' && ss[i + j] != t[j])
			{
				ok = false;
				break;
			}
			ss[i + j] = t[j];
		}
		if(ok && count(ss) == 1)
		{
			for(int j = 0;j < n;j ++)
			{
				if(ss[j] == '?')ss[j] = 'd';
			}
			F = true;
			cout << "Yes" << endl;
			cout << ss << endl;
			break;
		}
	}
	if(!F)cout << "No" << endl;	
}
int main()
{
#ifdef LOCAL
	auto start_time = clock();
	cerr << setprecision(3) << fixed; // 在iomanip中
#endif
	SIS;
	cin >> test;
	while(test--)
	{
		slove();
	}
#ifdef LOCAL
	auto end_time = clock();
	cerr << "Execution time: " << (end_time - start_time) * (int)1e3 / CLOCKS_PER_SEC << " ms\n";
#endif
}

#657Div2 - B

因为 m = na + b - c -> na = m + c - b

na -->[m - (r - l) ,m + (r - l)]

故我们需要枚举a 使得 n 满足 > 0 且,na 符合区间即可。

如果枚举出符合条件的数。我们再确定b 和 c 的值 因为我们取得的x = (b - c)

x 属于 [- (r - l) , (r - l) ] , 故 (b - c)要么 = - (r - l) 要么 = r - l

因此需要挨个断定 b 和 c 的值。

#include <bits/stdc++.h>
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define lowbit(x) (x & -x)
using namespace std;
typedef long long ll;
const int MAX = 0x7ffffff;
int t;

void slove()
{
	ll l , r , m , dis;
	cin >> l >> r >> m;
	dis = r - l;
	for(ll a = l ; a <= r ;a ++)
	{
		ll n = (m + dis) / a;
		if(n > 0 && n * a >= (m - dis) && n * a <= (m + dis))
		{
            // 挨个试探
			ll b = r;
			ll c = b - m + n * a;
			if(c > r)
			{
				b = l;
				c = b - m + n * a;
			}
			cout << a << " " << b << " " << c << endl;
			break;
		}
	}
}
int main()
{
#ifdef LOCAL
	auto start_time = clock();
	cerr << setprecision(3) << fixed; // 在iomanip中
#endif
	SIS;
	cin >> t;
	while(t--)
	{
		slove();
	}
#ifdef LOCAL
	auto end_time = clock();
	cerr << "Execution time: " << (end_time - start_time) * (int)1e3 / CLOCKS_PER_SEC << " ms\n";
#endif
}
上一篇:初识数据结构和算法


下一篇:Daliy Algorithm (heap,greedy , IQ )-- day 91