2016-2017 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2016)题解

news2024/11/18 15:19:34

2016-2017 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2016)

A - Artwork

题目描述:

给定N*M的网格,给出Q次询问,每次询问都给出一个小矩阵,保证每个矩阵要么长为1,要么宽为1,将网格中矩阵部分涂黑,每次询问都要回答到目前为止白色部分的联通块的数量

思路:

很经典的一种离线考察方法,先将所有询问保存下来,离线并查集处理

从后往前去取消覆盖,来获得答案

开一个二维数组记录网格被涂黑的次数,当次数变成0以后,就把它与上下左右四个方向进行合并,并更新联通块的数量

很简单的思路,不过写起来有点恶心

#include<bits/stdc++.h>
using namespace std;

#define m_p(a, b) make_pair(a, b)
#define endl '\n'
#define io ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define pb push_back
typedef long long ll;
typedef pair<int, int> pii;
#define MAX 1000050
#define y1 y114514
#define lowbit(x) (x&(-x))
int x, y, z, n, m, k;
int num[1005][1005];
struct ran{
	int x1, y1, x2, y2;
}tr[MAX];

int fa[1500005];
int getfa(int x){
	return fa[x] == x ? x : fa[x] = getfa(fa[x]);
}
int getid(int x, int y){
	return (x-1)*m + y;
}
bool judge(int x, int y){
	if(x > n || x < 1 || y > m || y < 1)return false;
	if(num[x][y])return false;
	return true;
}
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
void emerge(int x, int y){
	fa[getfa(x)] = getfa(y);
}
int ar[MAX];
void work(){
	cin >> n >> m >> k;
	for(int i = 1; i <= 1500000; ++i)fa[i] = i;
	for(int i = 1; i <= k; ++i){
		cin >> tr[i].x1 >> tr[i].y1 >> tr[i].x2 >> tr[i].y2;
		if(tr[i].x1 == tr[i].x2){
			for(int j = tr[i].y1; j <= tr[i].y2; ++j)++num[tr[i].x1][j];
		}
		else for(int j = tr[i].x1; j <= tr[i].x2; ++j)++num[j][tr[i].y1];
	}
	for(int i = 1; i <= n; ++i){
		for(int j = 1; j <= m; ++j){
			if(num[i][j])continue;
			for(int k = 0; k < 4; ++k){
				int xx = i + dx[k];
				int yy = j + dy[k];
				if(judge(xx, yy))emerge(getid(i,j), getid(xx, yy));
			}
		}
	}
	set<int>se;
	for(int i = 1; i <= n; ++i){
		for(int j = 1; j <= m; ++j){
			if(!num[i][j]){
				se.insert(getfa(getid(i, j)));	
			}
		}
	}
	int tot = (int)se.size();
	ar[k] = tot;
	for(int i = k; i > 1; --i){
		if(tr[i].x1 == tr[i].x2){
			for(int j = tr[i].y1; j <= tr[i].y2; ++j){
				--num[tr[i].x1][j];
				if(num[tr[i].x1][j] == 0){
					set<int>se;
					for(int p = 0; p < 4; ++p){
						int xx = tr[i].x1 + dx[p];
						int yy = j + dy[p];
						if(judge(xx, yy)){
							se.insert(getfa(getid(xx, yy)));
						}
					}
					tot = tot - se.size() + 1;
					int id = getid(tr[i].x1, j);
					fa[id] = id;
					for(auto x :se)fa[x] = id;
				}
			}
		}
		else{
			for(int j = tr[i].x1; j <= tr[i].x2; ++j){
				--num[j][tr[i].y1];
				if(num[j][tr[i].y1] == 0){
					set<int>se;
					for(int p = 0; p < 4; ++p){
						int xx = j + dx[p];
						int yy = tr[i].y1 + dy[p];
						if(judge(xx, yy)){
							se.insert(getfa(getid(xx, yy)));
						}
					}
					tot = tot - se.size() + 1;
					int id = getid(j, tr[i].y1);
					fa[id] = id;
					for(auto x :se)fa[x] = id;
				}
			}
		}
		ar[i-1] = tot;
	}
	for(int i = 1; i <= k; ++i)cout << ar[i] << " ";
	cout << endl;
}

int main(){
	io;
	work();
	return 0;
}
image-20230409213957156 image-20230409214019315

C Card Hand Sorting

题目描述:

给出n张有花色有数字的卡片,你每次可以将一张卡片移动到任意一个位置,问最少需要多少次可以将相同花色的卡片放在一起,且保证花色相同的卡片中数字是有序的(无论升序还是降序)

思路:

比赛的时候读假题了,三个人对着假代码思考了半个小时也没找出来哪里有问题,后来发现我读漏条件了,md

首先思考一下,假设给定一个最终状态,从原始状态变成最终状态最少需要多少步该怎么求?我们可以用最长公共子序列来求,由于每次操作只是将一个数字移动到一个新的位置,所以不需要操作的数字的位置是相对不变的,我们跟最终状态求一个最长公共子序列就能求出不需要移动的数字的数量,用长度减去找个数字就能求出最小操作次数

花色的数量只有4种,所以最多枚举4!种花色的排列方式,再此基础上可以再枚举一下每种花色是升序还是降序,也就是24

复杂度是 o ( 4 ! ∗ 2 4 ∗ n 2 ) o(4! * 2^4*n^2) o(4!24n2)

#include<bits/stdc++.h>
using namespace std;

#define MAX 300050

int n, m;
string cao[100];
map<char, int>bijiao;
char sr[] = {'s', 's', 'h', 'd', 'c'};
int dp[60][60];
int fuck(vector<string> s, vector<string> t){
	int len1 = s.size(), len2 = t.size();
	memset(dp, 0, sizeof(dp));
	for(int i = 1; i <= len1; ++i){
		for(int j = 1; j <= len2; ++j){
			if(s[i-1] == t[j-1]){
				dp[i][j] = dp[i - 1][j - 1] + 1;
			}
			else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
		}
	}
	return dp[len1][len2];
} 

vector<string> cnm(vector<string> v, bool op){
	for(int i = 0; i < v.size(); ++i){
		for(int j = i+1; j < v.size(); ++j){
			if(bijiao[v[i][0]] > bijiao[v[j][0]]){
				swap(v[i], v[j]);
			}
		}
	}
	if(op == 1)reverse(v.begin(), v.end());
	return v;
}

void work(){
	cin >> n;
	for(int i = 2; i <= 9; ++i){
		bijiao[(char)('0'+i)] = i;
	}
	bijiao['T'] = 10;
	bijiao['J'] = 11;
	bijiao['Q'] = 12;
	bijiao['K'] = 13;
	bijiao['A'] = 14;
	char x;
	map<char, int>mp;
	map<char, vector<string>>mpp;
	vector<string>s; 
	mp['s'] = 1;mp['h'] = 2;mp['d'] = 3;mp['c'] = 4; 
	for(int i = 1; i <= n; ++i){
		cin >> cao[i];
		s.push_back(cao[i]);
		x = cao[i][1];
		mpp[x].push_back(cao[i]);
	}
	int ar[] = {0, 1, 2, 3, 4};
	int ans = 1e9; 
	do{
		
		for(int i = 0; i < 16; ++i){
			vector<string>t;
			for(int j = 1; j <= 4; ++j){
				vector<string>aa = cnm(mpp[sr[ar[j]]], (i>>(j-1)&1));
				for(auto x : aa)t.push_back(x);
			}
			ans = min(ans, n - fuck(s, t));
		}
	}while(next_permutation(ar+1, ar+5));
	cout << ans << endl;
}

int main(){
	work();
	return 0; 
} 

D Daydreaming Stockbroker

题目描述:

给出一支股票在接下来n天内的价格,你的启动资金有100$,你可以在任意的天内买入或者卖出股票,数量任意,但不超过100000股(即你手中最多持有100000股),问在最后一天结束以后,你最多能拥有多少钱

思路:

贪心

如果今天的股票价格大于上一天的,就在i-1天的价格购入能买的最大数量支股票,以第i天的价格全卖出去,更新钱的数量

#include<bits/stdc++.h>
using namespace std;

#define m_p(a, b) make_pair(a, b)
#define endl '\n'
#define io ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define pb push_back
typedef long long ll;
typedef pair<int, int> pii;
#define MAX 1000050
#define y1 y114514
#define lowbit(x) (x&(-x))
ll x, y, z, n, m, k;
ll tr[MAX];

void work(){
	cin >> n;
	for(int i = 1; i <= n; ++i)cin >> tr[i];
	m = 100;
	for(int i = 2; i <= n; ++i){
		if(tr[i] > tr[i - 1]){
			k = min(100000ll, m / tr[i - 1]);
			m += k * (tr[i] - tr[i - 1]);
		}
	}
	cout << m << endl;
}

int main(){
	io;
	work();
	return 0;
}

F Fleecing the Raffle

题目描述:

n个球抓k个球的游戏,现在你可以往里放若干个球,使得自己中奖的概率最高,问概率最高是多少

思路:

推公式

image-20230410122221923
#include<bits/stdc++.h>
using namespace std;

#define MAX 300050

double n, p;

void work(){
	cin >> n >> p;
	double pre = 1.0*p/(n+1);
	double now = pre;
	for(double i = 2; ;++i){
		now = now * i / (i - 1) * (n - p + i) / (n+i);
		if(now<pre){
			printf("%.10f\n", pre);
			return;
		} 
		pre = now;
	}
}

int main(){
	work();
	return 0; 
} 

G Game Rank

题目描述:

模拟题,懒得复述题意了

#include<bits/stdc++.h>
using namespace std;

#define MAX 300050

int n, m;
int num[MAX] ;

void work(){
	string s;cin>>s;
	for(int i = 1; i <= 10; ++i)num[i] = 5;
	for(int i = 11; i <= 15; ++i)num[i] = 4;
	for(int i = 16; i <= 20; ++i)num[i] = 3;
	for(int i = 21; i <= 25; ++i)num[i] = 2;
	int star = 0;
	int grade = 25;
	int cont = 0;
	for(auto x : s){
		if(x == 'W'){
			++cont;
			++star;
			if(cont >= 3 && grade>=6)++star;
			if(star > num[grade] ){
				star -= num[grade];
				--grade;
			}
			if(grade == 0){
				cout << "Legend\n";
				return;
			}
		} 
		else{
			cont = 0;
			if(grade > 20 || grade == 0)continue;
			if(star){
				--star;
			}
			else{
				if(grade == 20)continue;
				++grade;
				star = num[grade] - 1; 
			}
		}
	}
	cout << grade <<endl;
}

int main(){
	work();
	return 0; 
} 

J Jumbled Compass

题目描述:

给你一个360度的罗盘,给出a和b所在的角度,问指针最少转动多少度可以从a转到b,顺时针是+,逆时针是-

思路:

枚举或者分类讨论一下

#include<bits/stdc++.h>
using namespace std;

void work(){
	int n, m;
	cin >> n >> m;
	m = (m - n + 360) % 360;
	int k = m - 360;
	if(abs(k) < abs(m))cout << k << endl;
	else cout << m << endl;
}

int main(){
	work();
	return 0; 
} 

总结

这是和wwy组队的第一场比赛,卡牌题我读漏了个条件,导致我们的思路虽然正确,但是漏了个花色内有序,所以卡了半个小时。而且由于时间限制,比赛只打了3个小时,导致A题一眼题但是没时间写,好像还有一个欧拉降幂的题,等有时间再补了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/419192.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最近给shopify跨境电商网站搞google搜索引擎的seo优化,整理了一些内容

接到一个网站&#xff0c;首先要做一些工作&#xff0c;然后按照这个步骤做好每一步&#xff0c;网站的搜索排名会有明显的效果。 对网站进行技术审核&#xff0c;以确保它符合搜索引擎的技术要求。研究关键词并确定目标关键词。优化网站内容&#xff0c;以便更好地针对目标关…

【LeetCode】剑指 Offer 55. 二叉树的深度 p271 -- Java Version

1. 题目介绍&#xff08;55. 二叉树的深度 &#xff09; 面试题55&#xff1a;二叉树的深度&#xff0c; 一共分为两小题&#xff1a; 题目一&#xff1a;二叉树的深度题目二&#xff1a;平衡二叉树 2. 题目1&#xff1a;二叉树的深度 题目链接&#xff1a;https://leetcode.c…

简单写一个Avue增删改查

今天练习了一下avue&#xff0c;真的好用&#xff0c;个人感觉相比于用element plus的组件还方便&#xff01; 简简单单的写了一个页面的增删改查&#xff0c;思路很简单。如果在写那种后台管理项目&#xff0c;基本上全是列表页&#xff0c;用这种方法写出来第一页&#xff0c…

收入下滑,亏损扩大的人力资源管理公司罗科仕申请纳斯达克IPO上市

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;来自北京的人力资源管理公司罗科仕近期已向美国证券交易委员会&#xff08;SEC&#xff09;提交招股书&#xff0c;申请在纳斯达克IPO上市&#xff0c;股票代码为(LGCL) 。罗科仕计划通过此次纳斯…

算法训练第五十八天 | 739. 每日温度、496.下一个更大元素 I

单调栈part01739. 每日温度题目描述思路496.下一个更大元素 I题目描述思路739. 每日温度 题目链接&#xff1a;739. 每日温度 参考&#xff1a;https://programmercarl.com/0739.%E6%AF%8F%E6%97%A5%E6%B8%A9%E5%BA%A6.html 题目描述 请根据每日 气温 列表&#xff0c;重新生…

Android组件化开发

Android组件开发 一、背景 一个app随着业务增加&#xff0c;代码放在同一个模块中会越来越臃肿&#xff0c;同时也导致多人开发的一个难度。组件化可以把业务单独分出来&#xff0c;形成一个单独模块&#xff0c;可单独运行、测试等&#xff0c;相互之间不会影响。另外一个优…

鼎捷T100制造之工艺工单实战(其他工艺补充)

文章目录 一、网状工艺二、平行工艺三、替代工艺四、返工工艺五、无顺序工艺一、网状工艺 网状工艺类似一张网状结构。可以包含平行和线性工艺等于一体。 网状工艺: 产品结构 aeci004:建立作业 aecm200: 工艺路线维护

kubeasz搭建k8s集群-部署单节点集群(AllinOne部署)

1说明 kubeasz 致力于提供快速部署高可用k8s集群的工具, 同时也努力成为k8s实践、使用的参考书&#xff1b;基于二进制方式部署和利用ansible-playbook实现自动化&#xff1b;既提供一键安装脚本, 也可以根据安装指南分步执行安装各个组件。 kubeasz 从每一个单独部件组装到完…

太赫兹高速通信系统前端关键技术

摘要&#xff1a;对构成太赫兹无线系统的2 种关键电路&#xff08;分谐波混频器和二倍频器&#xff09;进行了深入研究。在关键电路研究取得突破的基础上&#xff0c;开展了太赫兹无线通信技术研究&#xff0c;构建了220 GHz 无线通信实验验证系统。220 GHz 实验验证系统在室外…

elasticsearch 其他字段类型详解和范例

本章主要内容 elasticsearch 中别名字段的详解和范例elasticsearch 中二进制类型的详解和范例elasticsearch 中的嵌套类型的详解和范例elasticsearch 中的范围类型的详解和范例elasticsearch 中的排名类型的详解和范例elasticsearch 中的ip类型的详解和范例elasticsearch 中的…

【网络应用开发】实验3——Web组件重用与JavaBeans

目录 Web组件重用与JavaBeans预习报告 一、实验目的 二、实验原理 三、实验预习内容 1. 静态include指令何时执行&#xff1f;主页面和被包含的子页面是否转换为一个转换单元&#xff1f; 2.动作指令何时执行&#xff1f;主页面和被包含的子页面是否转换为一个转换单元&a…

【Python游戏】坦克大战、推箱子小游戏怎么玩?学会这些让你秒变高高手—那些童年的游戏还记得吗?(附Pygame合集源码)

前言 下一个青年节快到了&#xff0c;想小编我也是过不了几年节日了呢&#xff01;&#xff01; 社交媒体上流传着一张照片——按照国家规定“14岁到28岁今天都应该放半天假&#xff01;”不得不说&#xff0c; 这个跨度着实有点儿大&#xff0c;如果按整自然年来算年龄&…

Spark 连接 Hive

目录 导包 修改配置文件 修改hive-site.xml文件 启动hadoop 启动hive 启动spark 测试 查看表 导包 spark连接hive需要六个关键的jar包&#xff0c;以及将hive的配置文件hive-site.xml拷贝到spark的conf目录下。如果你hive配置没问题的话&#xff0c;这些jar都在hive的目…

Spring Security实战(四)—— 会话管理

目录 一、理解会话 二、防御会话固定攻击 三、会话过期 四、会话并发控制 五、集群会话的缺陷 六、集群会话的解决方案 七、整合Spring Session解决集群会话问题 只需在两个浏览器中用同一个账号登录就会发现&#xff0c;系统并没有任何会话并发限制。一个账号可以多处同…

cuSPARSE官方程序示例

cuSPARSE Library 简介 这个文件演示了cuSPARSE通用API的用法 官方程序&#xff1a;后续会出解析&#xff08;20230410&#xff09; cuSPARSE Generic APIs Documentation cuSPARSE Samples 向量 - 向量 操作矩阵 - 向量 操作矩阵 - 矩阵操作转换Legacy APIs优化稀疏迭代…

阿里本地生活再出发:口碑入高德,备战美团、抖音

配图来自Canva可画 近日&#xff0c;有传言称高德地图将和阿里本地生活旗下的到店业务口碑正式合并&#xff0c;未来阿里旗下所有的本地生活到店业务都将统一整合在高德地图的入口中。3月22日&#xff0c;高德地图正式确认了此事&#xff0c;并表示高德地图作为“出门好生活开…

网络软件-管理网络设备和组件

网络软件是一个术语&#xff0c;表示帮助网络管理员轻松执行特定操作的任何网络软件。术语“网络软件”可以包括广泛的软件解决方案&#xff0c;每个解决方案都提供特定的功能&#xff0c;共同帮助网络管理员完全控制其IT基础架构。网络软件工具提供监控网络运行状况、测量性能…

一个简单的MUX-VLAN实验(华为eNSP模拟器)

MUX-VLAN产生背景及用途 在数据中心网络中&#xff0c;数据中心管理员希望数据中心内部所有服务器&#xff08;或终端&#xff09;都可以访问外部网络&#xff0c;同时部分服务器之间可以互相通信&#xff0c;部分服务器之间相互隔离。一般情况下&#xff0c;为了实现所有服…

python贪吃蛇代码

文末用python写好了贪吃蛇代码可直接复制使用&#xff01; 今天和大家分享一下贪吃蛇的代码&#xff0c;主要是贪吃蛇的一些基本知识&#xff0c;以及怎么去玩。 首先&#xff0c;我们先了解一下什么是贪吃蛇&#xff1f;它是一个具有多种功能的游戏&#xff0c;可以通过点击屏…

绿联dx4600砖机救援

由于在操作ssh过程不当&#xff0c;导致成为搬砖&#xff0c;记录一下救援过程 涉及到拆机&#xff0c;会导致损保&#xff0c;建议邮寄官方救援 变砖前因&#xff1a; 发现可以使用opkg&#xff0c;遂用opkg进行安装包的操作&#xff0c;最后更新busy-box&#xff0c;而进行b…