Daliy Algorithm -- day 97

Nothing to fear


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

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

2020.8.1


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

H and W

指数型枚举的递推式枚举

指数型枚举的特点是,每一种状态只有选择/不选择两种状态

该类型的搜索实现方式有两种

1. 递推实现指数型枚举

我们需要只要枚举的状态一种由多少种选择
假设 存在 2^n 个选择
我们利用状态压缩来表示每一种状态
for(int i = 0;i < (1 << n) - 1;i ++)
{
    根据所选的状态操作
}

2. 递归实现指数型枚举

void dfs(int now)
{
    // 不选择当前状态
    dfs(now + 1);
    // 选择当前状态
    进行操作turn()
    dfs(now + 1);
    back() 恢复状态
}

在该样例中是多个状态联合起来 即一共存在 \(2 ^ {n + m}\)种状态集

#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;
const int MAX = 0x7ffffff;
int t , ans;
int n , m , k;
char a[7][7];
void check(int maskR , int maskC)
{
	int black = 0;
	for(int i = 0;i < n;i ++)
	{
		for(int j = 0;j < m;j ++)
		{
			if(((maskR >> i) & 1) == 0 && ((maskC >> j) & 1) == 0)
			{
				if(a[i][j] == '#')black++;
			}
		}
	}
	if(black == k)ans++;
}
void slove()
{	
	cin >> n >> m >> k;
	for(int i = 0;i < n;i ++)
		cin >> a[i];

	for(int i = 0; i <= (1 << n) - 1;i ++)
	{
		for(int j = 0;j <= (1 << m) - 1;j ++)
		{
			check(i , j);
		}
	}
	cout << ans << endl;
}
int main()
{
	SIS;
	slove();
}

Tsundoku

既然已经规定好了拿书本的方向我们考虑每次已经拿了N本书所消耗的时间,然后再去考虑在我们从 A 种拿了 x 本书之后还能在 B 种拿几本书。

由于该问题限定拿书的方向并且规定了要拿的书必须是第一本,于是否定了用dp来解决问题。

我们利用前缀和 suma 和 sumb 数组记录拿取 A 和 B数组中拿取第 i 本书时所花费的时间。

我们依次枚举从A中拿取 i 本书的情况下 从 B 中取 j 本书是否能满足 时间小于 k

如果直接暴力的话大概率会超时,我们使用一个简单的搜索外层从 0 - n枚举从 A 中 拿走 i 本书的情况

设置一个 j = m ,表示从 B 拿走 j 本书 ,因为显然当 A 中一本书都不拿的时候 B 中能拿的书的数目最多,于是我们让 j 逐渐递减当满足条件 sumb[j] > k - suma[i] 得时候。即枚举当前从A中 拿A本书从j中能拿的书的数目最多的情况。

#include <bits/stdc++.h>

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

void slove()
{
	int n , m , k;
	cin >> n >> m >> k;
	vector<ll> a(n + 1) , b(m + 1),suma(n + 1) , sumb(m + 1);
	for(int i = 1;i <= n;i ++)cin >> a[i];
	for(int i = 1;i <= m;i ++)cin >> b[i];
	for(int i = 1;i <= n;i ++)
		suma[i] = suma[i-1] + a[i];
	for(int i = 1;i <= m;i ++)
		sumb[i] = sumb[i-1] + b[i];
	ll ans = 0 , j = m;
	for(int i = 0;i <= n;i ++)
	{
		if(suma[i] > k)break;
		while(sumb[j] > k - suma[i])
			j--;
		ans = max(ans , i + j);
	}
	cout << ans << endl;
}
int main()
{
	SIS;
	slove();
}

该问题的内层循环也可以用二分解决

#include <bits/stdc++.h>

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

void slove()
{
	int n , m , k;
	cin >> n >> m >> k;
	vector<ll> a(n + 1) , b(m + 1),suma(n + 1) , sumb(m + 1);
	for(int i = 1;i <= n;i ++)cin >> a[i];
	for(int i = 1;i <= m;i ++)cin >> b[i];
	for(int i = 1;i <= n;i ++)
		suma[i] = suma[i-1] + a[i];
	for(int i = 1;i <= m;i ++)
		sumb[i] = sumb[i-1] + b[i];
	ll ans = 0 , j = m;
	for(int i = 0;i <= n;i ++)
	{
		if(k < suma[i])break;
		ll l = 0, r = m;
		ll val = k - suma[i];
		while(l < r)
		{
			int mid = l + r + 1 >> 1;
			if(sumb[mid] <= val)l = mid;
			else r = mid - 1;
		}
		if(l <= r)
			ans = max(ans, l + (ll)i);
		else ans = max(ans , (ll)i );
	}
	cout << ans << endl;
}
int main()
{
	SIS;
	slove();
}

十进制转26进制

#include <bits/stdc++.h>

#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define lowbit(x) (x & -x)
typedef long long ll;
using namespace std;
const int MAX = 0x7ffffff;
int t;
// 求一个数的26进制的表示形式
string dict = "abcdefghijklmnopqrstuvwxyz";
void slove()
{
	ll n;cin >> n;
	string s;
	while(n)
	{
		n--;
		int k = n % 26;
		s += dict[k];
		n /= 26;
	}
	reverse(s.begin() , s.end());
	cout << s << endl;
}
int main()
{
	SIS;
	slove();
}

Forbidden List

x , n = map(int , input().split())
p = list(map(int , input().split()))

for d in range(x + 1):
	for s in [-1, 1]:
		a = x + s * d 
		if p.count(a) == 0:
			print(a)
			exit(0)

: (Colon)

不要忘记时针会最真分针的转动而转动。心态崩了呀

为什么python的精度运算就是算不对啊 ,难道是精度太高了???

#include <bits/stdc++.h>

#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define lowbit(x) (x & -x)
#define PI 3.14159265358979323846264338327950L
typedef long long ll;
typedef long double ld;
using namespace std;
const int MAX = 0x7ffffff;
int t;
void slove()
{
	int a , b , h , m;
	cin >> a >> b >> h >> m;
	ld rad = PI * 2 * ((ld)h / 12.0 + ((ld)m / 60.0) / 12.0 - (ld)m / 60.0);
	ld rsq = (ld)(a*a + b*b) - (ld)(2*a*b)*cosl(rad);

	printf("%20.20Lf\n", sqrtl(rsq));
}
int main()
{
	SIS;
	slove();
}
posted @ 2020-08-02 10:15  _starsky  阅读(96)  评论(0编辑  收藏  举报