2023NOIP A层联测19 多边形

news/2025/2/21 11:29:56

题目大意

有一个正 n n n边形,每个点的颜色为红色、蓝色、绿色中的一种,保证每种颜色至少出现一次且 n n n边形上相邻的两个点颜色不同。你想要连接 n − 3 n-3 n3条对角线,使得对角线把图分成 n − 2 n-2 n2个三角形,并且每个三角形的三个顶点的颜色两两不同。

请输出任意一个合法的方案,有 n − 3 n-3 n3行,每行两个正整数 x , y x,y x,y,表示一条对角线。如果不存在合法方案,则输出 I m p o s s i b l e ! Impossible! Impossible!

样例输入

6
RBRGBG

样例输出

2 6
3 5
3 6

4 ≤ n ≤ 1 0 6 4\leq n\leq 10^6 4n106


题解

如果一个颜色只出现了一次,则因为相邻的两个点颜色不同,我们直接将这个点与所有其他点连接即可。

否则,一定会出现相邻三个点颜色两两不同,直接将这三个点划分为一个三角形,并删除中间那个点即可。可以发现,始终满足相邻的两个点颜色不同,所以这样做之后还是满足条件、可以继续删下去的。

当第一次出现有一种颜色只出现了一次的情况时,按上面所说,我们直接将这个点与所有其他点连接即可。

我们可以用链表来维护没有被删除的点,然后一路删下去即可。因为每种颜色至少出现一次,而且一直都不会出现两个点颜色相同的情况,所以在出现有一种颜色只出现一次的情况之前,总会出现相邻三个点颜色两两不同,总能一直删下去。那么, 就不会有无解的情况。

时间复杂度为 O ( n ) O(n) O(n)

code

#include<bits/stdc++.h>
using namespace std;
const int N=1000000;
int n,ct[3],v[N+5],l[N+5],r[N+5],z[N+5];
char s[N+5];
struct node{
	int x,y;
};
vector<node>ans;
void del(int i){
	z[i]=1;
	r[l[i]]=r[i];l[r[i]]=l[i];
}
void solve(){
	int bz=0;
	for(int i=1;i<=n;i++){
		if(!z[i]&&ct[v[i]]==1){
			bz=i;break;
		}
	}
	for(int i=1;i<=n;i++){
		if(!z[i]&&i!=bz&&l[i]!=bz&&r[i]!=bz){
			ans.push_back((node){bz,i});
		}
	}
	for(int i=0;i<ans.size();i++){
		printf("%d %d\n",ans[i].x,ans[i].y);
	}
}
int main()
{
//	freopen("polygon.in","r",stdin);
//	freopen("polygon.out","w",stdout);
	scanf("%d",&n);
	scanf("%s",s+1);
	for(int i=1;i<=n;i++){
		if(s[i]=='R') v[i]=0;
		else if(s[i]=='G') v[i]=1;
		else v[i]=2;
		++ct[v[i]];
	}
	for(int i=1;i<=n;i++){
		l[i]=i-1;r[i]=i+1;
	}
	l[1]=n;r[n]=1;
	if(ct[0]==1||ct[1]==1||ct[2]==1){
		solve();return 0;
	}
	for(int i=1;;i=r[i]){
		while(v[l[l[i]]]+v[l[i]]+v[i]==3){
			--ct[v[l[i]]];
			ans.push_back((node){l[l[i]],i});
			del(l[i]);
			if(ct[0]==1||ct[1]==1||ct[2]==1){
				solve();return 0;
			}
		}
	}
	return 0;
}

http://www.niftyadmin.cn/n/5128072.html

相关文章

eslint识别不了别名解决方法

第一步 npm i eslint-import-resolver-alias -D第二步&#xff1a;在 eslintrc.js 配置 module.exports {settings: {import/resolver: {alias: {map: [// 这里参照webpack的别名配置映射[, ./src]],// 引用的时候可以忽略后缀extensions: [.vue, .js, .ts, .tsx, .jsx, .json…

Qt中设置鼠标透明度的应用及示例

Qt中设置鼠标透明度的应用及示例 介绍设置鼠标透明度的方法应用场景遮罩层可视化效果 结论 介绍 Qt是一个功能强大的跨平台应用程序开发框架&#xff0c;可以用于开发各种类型的应用程序。在Qt中&#xff0c;我们可以设置鼠标的透明度&#xff0c;即将鼠标事件传递给下方的控件…

时间复杂度(补充)和 空间复杂度

大家好啊&#xff0c;我今天来给大家分享有关空间复杂度的知识。感谢大家对我的支持&#xff0c;我会继续加油更新博客&#xff0c;努力提高博客质量的。 我们在这里先补充时间复杂度的一些实例&#xff1a; 补充实例1&#xff1a; // 计算BinarySearch的时间复杂度&#xff…

【黑产攻防道03】利用JS参数更新检测黑产的协议破解

任何业务在运营一段时间之后都会面临黑产大量的破解。验证码和各种爬虫的关系就像猫和老鼠一样, 会永远持续地进行博弈。极验根据十一年和黑产博弈对抗的经验&#xff0c;将黑产的破解方式分为三类&#xff1a; 1.通过识别出验证码图片答案实现批量破解验证&#xff0c;即图片…

交易所(Exchange, ACM/ICPC NEERC 2006, UVa1598)rust解法

你的任务是为交易所设计一个订单处理系统。要求支持以下3种指令。 BUY p q&#xff1a;有人想买&#xff0c;数量为p&#xff0c;价格为q。 SELL p q&#xff1a;有人想卖&#xff0c;数量为p&#xff0c;价格为q。 CANCEL i&#xff1a;取消第i条指令对应的订单&#xff08;输…

hiredis C库调用的工具会话类封装。

调用函数&#xff1a; int32_t seasonId 0;{pRedisSession->commandF("HGET {} season_id", strArenaConfig);RedisReply r(pRedisSession->getReply());if (r.isString()){auto buffer r.getString();seasonId std::atoi(buffer.c_str());}} 头文件&…

设备管理软件管理系统

从设备检查到设备保养&#xff0c;再到设备维护&#xff0c;全方位视角掌握设备状态的管理软件。让企业员工可以随时随地的查看设备的各种信息&#xff1a;巡检信息、保养计划、备件更换提醒、维修保养资料等。 1、一物一码&#xff0c;建立设备电子档案“身份证” 精准管控每一…

剑指JUC原理-4.共享资源和线程安全性

共享问题 小故事 老王&#xff08;操作系统&#xff09;有一个功能强大的算盘&#xff08;CPU&#xff09;&#xff0c;现在想把它租出去&#xff0c;赚一点外快 小南、小女&#xff08;线程&#xff09;来使用这个算盘来进行一些计算&#xff0c;并按照时间给老王支付费用 …