您的位置:首页 > 其它

NOIP模拟题 [位运算][生成树]

2016-11-18 14:56 197 查看
如约而至。

愿不辜负。

说正事,不要因为写得很快而沾沾自喜,对拍要快快快一点啊啊啊!

然后推的时候要用变量代替样例数据,同时一定!要自己出数据。

还有,一定要在思路理清楚以后认真检查一次程序的逻辑关系,是否能达到要求,尤其是常数的使用。

静态差错一!定!要!认真看每一句,清醒一点呀喂!

现在脑子不太好使,很容易想不出来,每抓住一个可能的思路,不要因为问题而退缩,要想一下如果我要用这个方法的话我要怎么解决!

T1:

题意:

给定一序列,求每个数&,|每个数的和。

分析:

把每一位画出来会发现,针对当前数当前位是0或是1来进行处理即可。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<ctime>
#define ll long long
#define inf 2e8
#define clr(x) memset(x,0,sizeof(x))
#define maxen(x) memset(x,127,sizeof(x))
#define maxer(x) memset(x,31,sizeof(x))
#define minus(x) memset(x,-1,sizeof(x))
#define each(i,n,m) for(long long i=n;i<m;i++)
#define eachrev(i,n,m) for(long long i=n;i>m;i--)
#define minn(a,b,c) min(a,min(b,c))
#define maxx(a,b,c) max(a,max(b,c))
#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
#define PROC "believe"
//for(long long i=1;i<=n;i++)
//(double) (ll) LL (long long)
//(double)clock()/CLOCKS_PER_SEC
using namespace std;
const long long Maxn=1e5+5;
const long long modd=1e9+7;
long long n,a[Maxn];
long long b[20],c[20],ansb[Maxn],ansc[Maxn];
long long read()
{
long long x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10LL+ch-'0';ch=getchar();}
return x*f;
}
void init()
{
n=read();
for(long long i=1;i<=n;i++){
a[i]=read();
for(long long j=0;j<=17;j++)
if(a[i]&(1<<j)){
b[j]+=(long long)(1LL<<j);
c[j]+=(long long)(1LL<<j);
}
}
}
void work()
{
for(long long i=1;i<=n;i++)
for(long long j=0;j<=17;j++)
if(a[i]&(1LL<<j)){
ansb[i]+=b[j];
ansc[i]+=(long long)(n*(long long)(1LL<<j));
}
else ansc[i]+=c[j];
for(long long i=1;i<=n;i++)printf(lld" ",ansb[i]);
printf("\n");
for(long long  i=1;i<=n;i++)printf(lld" ",ansc[i]);
}
void work1()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
ansb[i]+=a[i]&a[j];
ansc[i]+=a[i]|a[j];
}
for(int i=1;i<=n;i++)printf(lld" ",ansb[i]);
printf("\n");
for(int i=1;i<=n;i++)printf(lld" ",ansc[i]);
}
int main()
{
freopen(PROC".in","r",stdin);
freopen(PROC".out","w",stdout);
init();
if(n>1000)work();
else work1();
//debug();
return 0;
}


T2:

题意:

要求从N个,每个有两个不同颜色的盒子里选出最多个数的盒子,使得其任意子集不会出现所有颜色数为偶数的情况。

分析:

对于两个点绑定了的情况,考虑建图,然后会发现,只要连成的图成了环,则出现了所有点度为偶数的最小情况,所以不能选。针对这种情况就不能选,由于加上一条边必须同时减去一条边,而它们的取舍不会对后面造成不同(因为其本质都是环的一部分),贪心走下去就可以了。

其实本质就是对于每个连通分量选一棵树。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<ctime>
#define ll long long
#define inf 2e8
#define clr(x) memset(x,0,sizeof(x))
#define maxen(x) memset(x,127,sizeof(x))
#define maxer(x) memset(x,31,sizeof(x))
#define minus(x) memset(x,-1,sizeof(x))
#define each(i,n,m) for(int i=n;i<m;i++)
#define eachrev(i,n,m) for(int i=n;i>m;i--)
#define minn(a,b,c) min(a,min(b,c))
#define maxx(a,b,c) max(a,max(b,c))
#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
#define PROC "heart"
//for(int i=1;i<=n;i++)
//(double) (ll) LL (int)
//(double)clock()/CLOCKS_PER_SEC
using namespace std;
const int Maxn=1e5+5;
const int modd=1e9+7;
int tot,fin,sta;
int n,m,fa[Maxn*2];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int findfa(int u)
{
return fa[u]=(fa[u]==u?u:findfa(fa[u]));
}
void init()
{
n=read();m=read();
for(int i=1;i<=m;i++)fa[i]=i;
for(int i=1;i<=n;i++){
sta=read();fin=read();
if(findfa(sta)!=findfa(fin)){
tot++;
fa[fa[sta]]=fa[fin];
}
}
}
void work()
{
printf("%d",tot);
}
int main()
{
freopen(PROC".in","r",stdin);
freopen(PROC".out","w",stdout);
init();
work();
//debug();
return 0;
}


T3:

题意:

对于T1,给出结果,输出满足的序列。

分析:

a&b+a|b=a+b,给的两个序列刚好是这两种运算,加起来解一下方程就可以了。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<ctime>
#define ll long long
#define inf 2e8
#define clr(x) memset(x,0,sizeof(x))
#define maxen(x) memset(x,127,sizeof(x))
#define maxer(x) memset(x,31,sizeof(x))
#define minus(x) memset(x,-1,sizeof(x))
#define each(i,n,m) for(long long i=n;i<m;i++)
#define eachrev(i,n,m) for(long long i=n;i>m;i--)
#define minn(a,b,c) min(a,min(b,c))
#define maxx(a,b,c) max(a,max(b,c))
#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
#define PROC "problem"
//for(long long i=1;i<=n;i++)
//(double) (ll) LL (long long)
//(double)clock()/CLOCKS_PER_SEC
using namespace std;
const long long Maxn=1e5+5;
const long long modd=1e9+7;
long long n,flg,res,cal;
long long tot[Maxn],ans[Maxn];
long long read()
{
long long x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10LL+ch-'0';ch=getchar();}
return x*f;
}
void init()
{
n=read();
for(long long i=1;i<=n;i++)tot[i]=read();
for(long long i=1;i<=n;i++)res+=(tot[i]+=read());
res/=2LL*n;
}
void work()
{
for(long long i=1;i<=n;i++)
if((tot[i]-res)%4LL)flg=1;
else ans[i]=(tot[i]-res)/4LL;

if(flg)printf("-1");
else for(int i=1;i<=n;i++)
printf(lld" ",ans[i]);
}
void debug()
{
//
}
int main()
{
freopen(PROC".in","r",stdin);
freopen(PROC".out","w",stdout);
init();
work();
//debug();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息