Codeforces Round #595 (Div. 3) A~E

A - Yet Another Dividing into Teams

因为给出的 n n n个数都是不一样的,所以有两个数相邻答案就是 2 2 2,否则就是 1 1 1

代码

#include <bits/stdc++.h>
#define pi acos(-1.0)
#define ll long long
#define lf double
#define ull unsigned long long
#define esp 1e-9
#define inf 0x3f3f3f3f
#define inff 0x3f3f3f3f3f3f3f3f
#define Pair pair<ll, ll>
#define It set<ll>::iterator
#define CLR(x, a) memset(x, a, sizeof(x))
    
using namespace std;
 
const ll N = 1e3+5;
ll T, n, m, vis[N];
 
int main(){
	ios::sync_with_stdio(false);
	cin>>T;
	while (T--){
		memset(vis, 0, sizeof(vis));
		cin>>n; ll f = 0;
		while (n--){
			cin>>m; vis[m] = 1;
			if (vis[m-1] || vis[m+1]){
				f = 1;
			}
		}
		cout<<f+1<<endl;
	}
	
	return 0;
}

B1 - Books Exchange (easy version)

n n n最大 200 200 200,模拟走一遍。

代码

#include <bits/stdc++.h>
#define pi acos(-1.0)
#define ll long long
#define lf double
#define ull unsigned long long
#define esp 1e-9
#define inf 0x3f3f3f3f
#define inff 0x3f3f3f3f3f3f3f3f
#define Pair pair<ll, ll>
#define It set<ll>::iterator
#define CLR(x, a) memset(x, a, sizeof(x))
    
using namespace std;
 
const ll N = 1e3+5;
ll T, n, a[N];
 
int main(){
	ios::sync_with_stdio(false);
	cin>>T;
	while (T--){
		cin>>n;
		for (ll i = 1; i <= n; i++){
			cin>>a[i];
		}
		for (ll i = 1; i <= n; i++){
			ll tmp = a[i], cnt = 1;
			while (tmp != i){
				tmp = a[tmp]; cnt++;
			}
			cout<<cnt<<" ";
		}
		cout<<endl;
	}
	
	return 0;
}

B2 - Books Exchange (hard version)

n n n有点大,仔细想一下, n n n个数是一个排列,用并查集把他们分为几个联通块,答案其实就是它所在联通块内点的个数(画个图,每个联通块连成一个圈,瞅一瞅就感觉很有道理)。

代码

#include <bits/stdc++.h>
#define pi acos(-1.0)
#define ll long long
#define lf double
#define ull unsigned long long
#define esp 1e-9
#define inf 0x3f3f3f3f
#define inff 0x3f3f3f3f3f3f3f3f
#define Pair pair<ll, ll>
#define It set<ll>::iterator
#define CLR(x, a) memset(x, a, sizeof(x))
    
using namespace std;
 
const ll N = 2e5+5;
ll T, n, m, f[N], cnt[N];
 
ll find(ll x){
	return f[x] = (f[x]==x ? x : find(f[x]));
}
 
int main(){
	ios::sync_with_stdio(false);
	cin>>T;
	while (T--){
		cin>>n;
		for (ll i = 1; i <= n; i++){
			f[i] = i; cnt[i] = 1;
		}
		for (ll i = 1; i <= n; i++){
			cin>>m;
			ll fu = find(i), fv = find(m);
			if (fu != fv){
				f[fu] = fv;
				cnt[fv] += cnt[fu];
			}
		}
		for (ll i = 1; i <= n; i++){
			cout<<cnt[find(i)]<<" ";
		}
		cout<<endl;
	}
	
	return 0;
}

C1 - Good Numbers (easy version)

打个表丢进set,lower_bound直接莽。

代码

#include <bits/stdc++.h>
#define pi acos(-1.0)
#define ll long long
#define lf double
#define ull unsigned long long
#define esp 1e-9
#define inf 0x3f3f3f3f
#define inff 0x3f3f3f3f3f3f3f3f
#define Pair pair<ll, ll>
#define It set<ll>::iterator
#define CLR(x, a) memset(x, a, sizeof(x))
    
using namespace std;
 
const ll N = 2e5+5;
ll T, n;
set<ll> st;
 
int main(){
	ios::sync_with_stdio(false);
	ll tmp = 1, sum = 1;
	for (ll i = 1; i < 1LL<<15; i++){
		ll tmp = i, sum = 0, tt = 1;
		while (tmp){
			if (tmp & 1){
				sum += tt;
			}
			tt *= 3;
			tmp >>= 1;
		}
		st.insert(sum);
	}
	cin>>T;
	while (T--){
		cin>>n;
		cout<<*st.lower_bound(n)<<endl;
	}
	
	return 0;
}

C2 - Good Numbers (hard version)

{ 1 , 2 , 3 , 4... } \{1, 2, 3, 4...\} {1,2,3,4...}这个序列中的数,如果把它看作二进制的一个状态再把它变成三进制所对应的的数,会发现它是递增的(乱莽)。。。比如 1 1 1 3 3 3的二进制为 01 01 01 11 11 11,所对应的三进制数就是 1 = 1 ∗ 3 0 1=1*3^0 1=130 4 = 1 ∗ 3 1 + 1 ∗ 3 0 4=1*3^1+1*3^0 4=131+130,打个表发现最多到 3 38 3^{38} 338,然后就直接二分, 冲冲冲。

代码

#include <bits/stdc++.h>
#define pi acos(-1.0)
#define ll long long
#define lf double
#define ull unsigned long long
#define esp 1e-9
#define inf 0x3f3f3f3f
#define inff 0x3f3f3f3f3f3f3f3f
#define Pair pair<ll, ll>
#define It set<ll>::iterator
#define CLR(x, a) memset(x, a, sizeof(x))
    
using namespace std;
 
const ll N = 2e5+5;
ll T, n;
 
int main(){
	ios::sync_with_stdio(false);
	cin>>T;
	while (T--){
		cin>>n;
		ll l = 1, r = 1LL<<38, ans;
		while (l <= r){
			ll mid = (l+r)/2, tmp = mid, sum = 0, tt = 1;
			while (tmp){
				if (tmp & 1){
					sum += tt;
				}
				tt *= 3; tmp >>= 1;
			}
			if (sum >= n){
				ans = sum; r = mid-1;
			}
			else{
				l = mid+1;
			}
		}
		cout<<ans<<endl;
	}
	
	return 0;
}

D1 - Too Many Segments (easy version)

反过来想,加入最多的线段数,让点被覆盖的次数小于等于 k k k
按线段右端点排序,若右端点相同则长度短的优先(肯定是优先考虑短的呗,因为影响的点数越小)。

代码

#include <bits/stdc++.h>
#define pi acos(-1.0)
#define ll long long
#define lf double
#define ull unsigned long long
#define eps 1e-9
#define inf 0x3f3f3f3f
#define inff 0x3f3f3f3f3f3f3f3f
#define Pair pair<ll, ll>
#define It map<int, int>::iterator
    
using namespace std;
 
struct node{
	ll l, r, idx;
	friend bool operator < (node a, node b){
		if (a.r == b.r){
			return a.l>b.l;
		}
		return a.r<b.r;
	}
};
 
const ll N = 2e3+5;
ll n, k, c[N], vis[N];
node line[N];
 
int main() {
	ios::sync_with_stdio(false);
	cin>>n>>k;
	for (ll i = 1; i <= n; i++){
		cin>>line[i].l>>line[i].r; line[i].idx = i;
	}
	sort(line+1, line+n+1);
	ll cnt = 0;
	memset(c, 0, sizeof(c));
	memset(vis, 0, sizeof(vis));
	for (ll i = 1; i <= n; i++){
		for (ll j = line[i].l; j <= line[i].r; j++){
			c[j]++;
		}
		ll f = 1;
		for (ll j = line[i].l; j <= line[i].r; j++){
			if (c[j] > k){
				f = 0;
				break;
			}
		}
		if (f){
			cnt++; vis[line[i].idx] = 1;
		}
		else{
			for (ll j = line[i].l; j <= line[i].r; j++){
				c[j]--;
			}	
		}
	}
	cout<<n-cnt<<endl;
	for (ll i = 1; i <= n; i++){
		if (!vis[i]){
			cout<<i<<" ";
		}
	}
	
	return 0;
}

D2 - Too Many Segments (hard version)

贪心思路已经找到了,接下来区间变多变长了。
那就用线段树区间查询+更新最大值呗,如果这个线段所在区间的最大值+1小于等于 k k k,则这个区间可取,区间最大值+1。

代码

#include <bits/stdc++.h>
#define pi acos(-1.0)
#define ll long long
#define lf double
#define ull unsigned long long
#define eps 1e-9
#define inf 0x3f3f3f3f
#define inff 0x3f3f3f3f3f3f3f3f
#define Pair pair<ll, ll>
#define It map<int, int>::iterator
    
using namespace std;
 
struct node{
	ll l, r, idx;
	friend bool operator < (node a, node b){
		if (a.r == b.r){
			return a.l>b.l;
		}
		return a.r<b.r;
	}
};
 
struct tree_node{
	ll l, r, maxx;
};
 
const ll N = 2e5+5;
ll n, k, vis[N], lazy[20*N];
node line[N];
tree_node tree[20*N];
 
void PushUp(ll rt){
	tree[rt].maxx = max(tree[rt<<1].maxx, tree[rt<<1|1].maxx);
}
 
void PushDown(ll rt){
	if (lazy[rt]){
		lazy[rt<<1] += lazy[rt]; tree[rt<<1].maxx += lazy[rt];
		lazy[rt<<1|1] += lazy[rt]; tree[rt<<1|1].maxx += lazy[rt];
		lazy[rt] = 0;
	}
}
 
void build(ll l, ll r, ll rt){
	tree[rt].l = l; tree[rt].r = r; lazy[rt] = 0;
	if (l == r){
		tree[rt].maxx = 0;
	}
	else{
		ll mid = (l+r)/2;
		build(l, mid, rt<<1);
		build(mid+1, r, rt<<1|1);
		PushUp(rt);
	}
}
 
ll query(ll l, ll r, ll rt){
	if (tree[rt].l==l && tree[rt].r==r){
		return tree[rt].maxx;
	}
	else{
		PushDown(rt);
		ll mid = (tree[rt].l+tree[rt].r)/2;
		if (r <= mid){
			return query(l, r, rt<<1);
		}
		else if (l >= mid+1){
			return query(l, r, rt<<1|1);
		}
		else{
			return max(query(l, mid, rt<<1), query(mid+1, r, rt<<1|1));
		}
	}
}
 
void update(ll l, ll r, ll rt){
	if (tree[rt].l==l && tree[rt].r==r){ 
		lazy[rt] += 1; tree[rt].maxx += 1;
		return ;
	}
	if (tree[rt].l != tree[rt].r){
		PushDown(rt);
		ll mid = (tree[rt].l+tree[rt].r)/2;
		if (r <= mid){
			update(l, r, rt<<1);
		}
		else if (l >= mid+1){
			update(l, r, rt<<1|1);
		}
		else{
			update(l, mid, rt<<1);
			update(mid+1, r, rt<<1|1);
		}
		PushUp(rt);
	}
}
 
int main() {
	ios::sync_with_stdio(false);
	cin>>n>>k;
	build(1, N, 1);
	for (ll i = 1; i <= n; i++){
		cin>>line[i].l>>line[i].r; line[i].idx = i;
	}
	sort(line+1, line+n+1);
	ll cnt = 0;
	memset(vis, 0, sizeof(vis));
	for (ll i = 1; i <= n; i++){
		ll tmp = query(line[i].l, line[i].r, 1);
		if (tmp+1 <= k){
			update(line[i].l, line[i].r, 1); 
			cnt++; vis[line[i].idx] = 1;
		}
	}
	cout<<n-cnt<<endl;
	for (ll i = 1; i <= n; i++){
		if (!vis[i]){
			cout<<i<<" ";
		}
	}
	
	return 0;
}

E - By Elevator or Stairs?

d p [ i ] [ 1 ] dp[i][1] dp[i][1] d p [ i ] [ 2 ] dp[i][2] dp[i][2]分别代表到第 i i i层走楼梯和坐电梯的最少时间。
d p [ i ] [ 1 ] = m i n ( d p [ i − 1 ] [ 1 ] , d p [ i − 1 ] [ 2 ] ) + a [ i ] dp[i][1] = min(dp[i-1][1], dp[i-1][2])+a[i] dp[i][1]=min(dp[i1][1],dp[i1][2])+a[i]
d p [ i ] [ 2 ] = m i n ( d p [ i − 1 ] [ 1 ] + c + b [ i ] , d p [ i − 1 ] [ 2 ] + b [ i ] ) dp[i][2] = min(dp[i-1][1]+c+b[i], dp[i-1][2]+b[i]) dp[i][2]=min(dp[i1][1]+c+b[i],dp[i1][2]+b[i])

代码

#include <bits/stdc++.h>
#define pi acos(-1.0)
#define ll long long
#define lf double
#define ull unsigned long long
#define eps 1e-9
#define inf 0x3f3f3f3f
#define inff 0x3f3f3f3f3f3f3f3f
#define Pair pair<ll, ll>
#define It map<int, int>::iterator
    
using namespace std;

const ll N = 2e5+5;
ll n, c, a[N], b[N], dp[N][5];

int main() {
	ios::sync_with_stdio(false);
	cin>>n>>c;
	memset(dp, 0, sizeof(dp));
	for (ll i = 2; i <= n; i++){
		cin>>a[i];
	}
	for (ll i = 2; i <= n; i++){
		cin>>b[i];
	}
	dp[2][1] = min(dp[1][1], dp[1][2])+a[2];
	dp[2][2] = c+b[2];
	cout<<0<<" "<<min(dp[2][1], dp[2][2])<<" ";
	for (ll i = 3; i <= n; i++){
		dp[i][1] = min(dp[i-1][1], dp[i-1][2])+a[i];
		dp[i][2] = min(dp[i-1][1]+c+b[i], dp[i-1][2]+b[i]);
		cout<<min(dp[i][1], dp[i][2])<<" ";
	}
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码下载:完整代码,可直接运行 ;运行版本:2022a或2019b或2014a;若运行有问题,可私信博主; **仿真咨询 1 各类智能优化算法改进及应用** 生产调度、经济调度、装配线调度、充电优化、车间调度、发车优化、水库调度、三维装箱、物流选址、货位优化、公交排班优化、充电桩布局优化、车间布局优化、集装箱船配载优化、水泵组合优化、解医疗资源分配优化、设施布局优化、可视域基站和无人机选址优化 **2 机器学习和深度学习方面** 卷积神经网络(CNN)、LSTM、支持向量机(SVM)、最小二乘支持向量机(LSSVM)、极限学习机(ELM)、核极限学习机(KELM)、BP、RBF、宽度学习、DBN、RF、RBF、DELM、XGBOOST、TCN实现风电预测、光伏预测、电池寿命预测、辐射源识别、交通流预测、负荷预测、股价预测、PM2.5浓度预测、电池健康状态预测、水体光学参数反演、NLOS信号识别、地铁停车精准预测、变压器故障诊断 **3 图像处理方面** 图像识别、图像分割、图像检测、图像隐藏、图像配准、图像拼接、图像融合、图像增强、图像压缩感知 **4 路径规划方面** 旅行商问题(TSP)、车辆路径问题(VRP、MVRP、CVRP、VRPTW等)、无人机三维路径规划、无人机协同、无人机编队、机器人路径规划、栅格地图路径规划、多式联运运输问题、车辆协同无人机路径规划、天线线性阵列分布优化、车间布局优化 **5 无人机应用方面** 无人机路径规划、无人机控制、无人机编队、无人机协同、无人机任务分配 **6 无线传感器定位及布局方面** 传感器部署优化、通信协议优化、路由优化、目标定位优化、Dv-Hop定位优化、Leach协议优化、WSN覆盖优化、组播优化、RSSI定位优化 **7 信号处理方面** 信号识别、信号加密、信号去噪、信号增强、雷达信号处理、信号水印嵌入提取、肌电信号、脑电信号、信号配时优化 **8 电力系统方面** 微电网优化、无功优化、配电网重构、储能配置 **9 元胞自动机方面** 交通流 人群疏散 病毒扩散 晶体生长 **10 雷达方面** 卡尔曼滤波跟踪、航迹关联、航迹融合

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值