这把爆零居然才扣110,应该扣个200+让我刻骨铭心才对。前三题都是偏思维的,也不难,然而我恰好过了三题的pre然后全挂。
根据唯一分解定理,素数的整数幂必问,这样才能分辨出来。其他的数不用问,因为可以表示为素数整数幂的乘积。
#include <bits/stdc++.h>
using namespace std;
bool flag[1010];
int ans[1010];
bool prime[1010];
int main(){
for(int i=2;i<=32;i++){
for(int j=i*2;j<=1000;j+=i){
prime[j]=1;
}
}
int n;
while(cin>>n){
int k=0;
for(int i=2;i<=n;i++){
if(prime[i])continue;
int cur=i;
if(!flag[i]){
while(cur<=n){
ans[k++]=cur;
flag[cur]=1;
cur*=i;
}
}
}
cout<<k<<endl;
for(int i=0;i<k;i++){
cout<<ans[i]<<" ";
}
}
return 0;
}
有两种情况输出YES,第一种,有在原位置的数(循环长度为1),这种情况下拿其他所有数和它连边就行了;第二种,存在长度为2的循环,且其他所有循环的长度均为偶数,这种情况下,假设长度为2的循环是x,y,xy连一条边,对于其他的循环,循环内的数轮流连x和y。大家可以试着出奇数长度的循环和没有长度为2的循环的情况,很容易就明白了,在这样的情况下,需要大于n条边才能使得图不矛盾。
#include <bits/stdc++.h>
using namespace std;
int a[100010];
bool vis[100010];
int cnt[100010];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
bool one=0;
bool two=0;
int root=0;
bool odd=0;
int x;
int y;
for(int i=1;i<=n;i++){
if(!vis[i]){
int cur=a[i];
while(!vis[cur]){
vis[cur]=1;
cur=a[cur];
cnt[i]++;
}
if(cnt[i]==1){
one=1;
root=i;
}
if(cnt[i]==2){
two=1;
x=i;
y=a[i];
}
if(cnt[i]>2){
if(cnt[i]&1)odd=1;
}
}
}
if(one){
cout<<"YES"<<endl;
for(int i=1;i<=n;i++){
if(i!=root){
printf("%d %d\n",root,i);
}
}
}else{
if(two&&(!odd)){
cout<<"YES"<<endl;
memset(vis,0,sizeof(vis));
printf("%d %d\n",x,y);
for(int i=2;i<=n;i++){
if(vis[i])continue;
if(i!=y&&i!=x){
int cur=a[i];
int q=0;
while(!vis[cur]){
vis[cur]=1;
cur=a[cur];
if(q&1){
printf("%d %d\n",x,cur);
}else{
printf("%d %d\n",y,cur);
}
q++;
}
}
}
}else{
cout<<"NO"<<endl;
}
}
return 0;
}
分块。可以把横坐标分为1000份,每份长度为1000,在每个区间内,将点按纵坐标排序,轮流升序/降序输出。这样大致是一个蛇形的顺序,可以证明最坏情况下总距离不会超过限制。
#include <bits/stdc++.h>
using namespace std;
struct point{
int x,y;
int id;
point(int x,int y):x(x),y(y){
}
point(){
}
bool operator<(const point &other)const{
return x<other.x;
}
};
point pts[1000010];
vector<point> vpts[1005];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
scanf("%d%d",&pts[i].x,&pts[i].y);
pts[i].id=i;
vpts[pts[i].y/1000].push_back(pts[i]);
}
for(int i=0;i<=1000;i++){
sort(vpts[i].begin(),vpts[i].end());
}
for(int i=0;i<=1000;i++){
if(i&1){
for(int k=0;k<vpts[i].size();k++){
printf("%d ",vpts[i][k].id);
}
}else{
for(int k=vpts[i].size()-1;k>=0;k--){
printf("%d ",vpts[i][k].id);
}
}
}
return 0;
}