题目链接
题目翻译:
今天幼儿园来了n个新小朋友,需要被安排到饭桌。饭桌的椅子从1到4n编号。两个小朋友不能坐同一张椅子。如果两个小朋友坐到编号为a和b的椅子上(a≠b),并且a和b满足以下条件的话,两个小朋友将会是淘气的:
- gcd(a,b) = 1 或者,
- a 整除 b 或者 b 整除 a 。
gcd(a,b)表示a和b的最大公约数。
比如,如果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;
}
总结:
虽然…但是感觉自己的知识增加了呢!