codeforces Round #681 (Div. 2) 1443A Kids Seating

题目链接

在这里插入图片描述

题目翻译:

今天幼儿园来了n个新小朋友,需要被安排到饭桌。饭桌的椅子从1到4n编号。两个小朋友不能坐同一张椅子。如果两个小朋友坐到编号为ab的椅子上(a≠b),并且ab满足以下条件的话,两个小朋友将会是淘气的:

  • gcd(a,b) = 1 或者,
  • a 整除 b 或者 b 整除 a 。

gcd(a,b)表示ab的最大公约数。
比如,如果n = 3,并且小朋友们坐到2,3,4号椅子上,那么他们将会是淘气的,因为4能被2整除,并且gcd(2,3) = 1。如果小朋友们坐到4,6,10号椅子上,那么他们就不淘气。
老师不想餐桌变得混乱,所以她想让任意两个小朋友都不是淘气的。
因为老师特别忙,所以请你来解决这个问题。

我的解题思路(建议跳过,看官方的):

首先能想到的是,这一定是一段由偶数组成的序列,且不包含2,这样所有元素的最大公约数就至少是2,另外只要满足其中的元素都不能被序列中的其他数整除就行了。
于是就开始找出n=1,n=2,…n=8时的序列,看看能不能找出什么规律。
在这里插入图片描述
除了n=1,其他的似乎是3个一组,每组数的开头都是一样的,数的增加不是2就是4。
可以算出起始数和n之间的关系是start=(n-2)/3*4+4,然后每次添加数字的时候,判断一下是否能和已存在的数整除,都不能的话就把这个数添加进去,否则就把这个数+2,直到不能和已存在的数整除。
十分幸运地是,这样做是对的,但是我并不能讲出个所以然…

我的代码:
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
#define inf 0x3f3f3f3f
using namespace std;
vector<int>v;
int main(){
//	freopen("1.txt","r",stdin);
	int t,n;
	cin>>t;
	while(t--){
		cin>>n;
		v.clear();
		int a=(n-2)/3*4+4;
		v.push_back(a);
		cout<<a;
		for(int i=1;i<n;i++){
			while(true){
				a+=2;
				int flag=0;
				for(int j=0;j<v.size();j++){
					if(a%v[j]==0){
						flag=1;
						break;
					}
				}
				if(flag==0){
					v.push_back(a);
					break;
				}
			}
			cout<<" "<<a;
		}
		cout<<endl;
	}
	return 0;
}
官方的解题思路:

直接从4n开始,取出n个偶数。
首先可以确定,这n个数中任意两个数的最大公约数一定大于等于2,因为都是偶数嘛。
其次,这n个数中最小的数比最大的数的一半还大2,因此肯定不存在能整除的数。因为一个数m,要找到一个m整除的数,这个数一定小于等于m/2。
在这里插入图片描述

代码:
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
#define inf 0x3f3f3f3f
using namespace std;
int main(){
//	freopen("1.txt","r",stdin);
	int t,n;
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=4*n;i>=2*n+2;i-=2){
			if(i!=4*n) cout<<" ";
			cout<<i;
		}
		cout<<endl;
	}
	return 0;
}
总结:

虽然…但是感觉自己的知识增加了呢!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值