目录
6614 、AND Minimum Spanning Tree 思维
6614 、AND Minimum Spanning Tree 思维
题意:
给出一个完全图,权值是两个点的and值,计算最小生成树,并输出与每个节点相连的节点(字典序最小)
分析:
可以很明显的知道偶数点与1and值永远是0,而对于奇数点,要使边权最小,那么取最低位0即可,这样and值也是0,如果最低位都比n大,那么显然连到1代价最小。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int res[maxn];
int lowbit(int i){
return i&(-i);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
int ans=0;
for(int i=2;i<=n;i++){
if(i&1){
int tmp=~i;
tmp=lowbit(tmp);
if(tmp>n) tmp=1,ans++;
res[i]=tmp;
}else res[i]=1;
}
printf("%d\n",ans);
for(int i=2;i<=n;i++){
if(i!=2) printf(" ");
printf("%d",res[i]);
}
printf("\n");
}
return 0;
}
6620、 Just an Old Puzzle 逆序对
题意:
给出15数码,计算是否有解。
分析:
这个题是POJ2893的弱化版,另一篇博客有详细说明
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=20;
int a[maxn],c[maxn];
int lowbit(int i){
return i&(-i);
}
void insert(int i,int x){
for(;i<maxn;i+=lowbit(i)){
c[i]+=x;
}
}
int getsum(int i){
int sum=0;
for(;i;i-=lowbit(i)){
sum+=c[i];
}
return sum;
}
int main(){
int n,m;
int T;
scanf("%d",&T);
while(T--){
n=4,m=4;
int x,sum=0,num=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int b;
scanf("%d",&b);
if(b){
a[num++]=b;
}else x=n-i;
}
}
memset(c,0,sizeof c);
for(int i=num-1;i>=0;i--){
sum+=getsum(a[i]-1);
insert(a[i],1);
}
if((x^sum)&1) printf("No\n");
else printf("Yes\n");
}
return 0;
}