二进制是计算技术中广泛采用的一种数制 。二进制数据是用0和1两个数码来表示的数 。利用二进制的特点 ,可以用于枚举一个集合中各元素的所有组合情况 。
例如 ,设某集合M中有3个元素A 、B和C ,即M={A ,B ,C} 。可以用3位二进制数来枚举3个元素的各种组合情况(也可以称为子集) ,每一位二进制数字对应一个元素 ,1表示选中 ,0表示不选 。
二进制数 001 ,表示选中A元素 ,B和C元素不选择 ,即子集为 { A };
二进制数 010 ,表示选中B元素,A和C元素不选择 ,即子集为 { B };
二进制数 011 ,表示选中A和B元素,C元素不选择 ,即子集为 { A ,B };
二进制数 100 ,表示选中C元素 ,A和B元素不选择 ,即子集为 { C };
二进制数 101 ,表示选中A和C元素 ,B元素不选择 ,即子集为 { A ,C };
二进制数 110 ,表示选中B和C元素 ,A元素不选择 ,即子集为 { B,C };
二进制数 111 ,表示选中A 、B和C这3个元素均选中 ,即子集为 { A,B ,C };
当然 ,二进制数000表示3个元素均不选择 ,就是子集是空集 。
这样 ,用循环 for (int i = 0; i < (1 << n); i++) 就可以遍历每一个子集 ,即遍历各种组合情况 。其中 (1 << n)表示 2n ,2n-1就对应n为二进制数 ,各位上的数字均为1 。
然后 ,可以利用二进制的位运算 ,来判断二进制数的某一位上是0还是1 。
二进制位运算的左移运算 a << b就表示把a转为二进制后左移b位(即在后面添b个0) 。
这样 , 1<<0=1(0) ; 1<<1=2 (10); 1<<2=4 (100); 1<<3=8 (1000);
……
因此 ,要判断一个二进制数x的第k位上是0还是1 ,只需计算 x & (1<<K),若计算出来的值为0 ,则x的第k位为0;若计算出来的值非0 ,则x的第k位为0 。
这样,再利用循环
For (int j = 0; j < n; j++)
if (i & (1 << j)) { … }
就可以对每一个子集中所选取的具体元素进行处理 。
编写如下的示例程序。
该程序运行后 ,输入3 ,可以输出A 、B 、C这3个元素的8中组合情况 。运行结果如下所示 。
下面通过一些实例来看二进制枚举的应用方法。
【例1】最接近的和
问题描述
给出两个整数n(n≤20)和b ,然后给出n个整数h1 、h2 、… 、hn 。问如何在这n个整数里面选择若干个数使得它们的和在满足大于等于b的情况下最小 ,并输出这个和与b的差 。
输入
第1行:2个用空格隔开的整数:N和B 。
第2…N+1行:第i+1行是1个整数:Hi 。
输出
输出1个非负整数 ,即满足大于等于b的情况下的最小和值与b的差 。
输入样例
5 16
3
1
3
5
6
输出样例
1
(1)编程思路 。
直接套用上面的二进制枚举的模板对h1 、h2 、… 、hn这n个元素的各种组合情况进行处理 。只是在具体处理时 ,将每次挑选中的元素累加起来 。当和值大于等于b时 ,记录最小的和值即可 。
(2)源程序 。
#include <stdio.h>
int main()
{
int n,b;
scanf("%d%d",&n,&b);
int i,j,h[21];
for (i=0;i<n;i++)
scanf("%d",&h[i]);
int ans=0x3f3f3f3f;
for (i=0; i<(1<<n); i++) // 枚举从0~2^n-1中组合情况
{
int sum=0;
for (j = 0; j < n; j++) // 遍历二进制的每一位
{
if (i & (1 << j)) // 判断二进制第j位是否为1 ,若为1 ,表示元素选中
{
sum+=h[j]; // 如果第j个元素选中 ,则加上它
}
}
if (sum>=b)
{
if (sum<ans) ans=sum;
}
}
printf("%d\n",ans-b);
return 0;
}
将上面的源程序提交给 洛谷题库P2677 [USACO07DEC]Bookshelf 2 B(https://www.luogu.com.cn/problem/P2677) ,可以Accepted 。
【例2】权利指数
问题描述
在选举问题中 ,总共有n个小团体,每个小团体拥有一定数量的选票数 。如果其中m个小团体的票数和超过总票数的一半 ,则此组合为“获胜联盟 ”。n个团体可形成若干个获胜联盟 。一个小团体要成为一个“关键加入者 ”的条件是:在其所在的获胜联盟中 ,如果缺少了这个小团体的加入,则此联盟不能成为获胜联盟 。一个小团体的权利指数是指:一个小团体在所有获胜联盟中成为“关键加入者 ”的次数。请你计算每个小团体的权利指数 。
输入
输入数据的第一行为一个正整数T ,表示有T组测试数据 。每一组测试数据的第一行为一个正整数n(0<n<=20) 。第二行有n个正整数 ,分别表示1到n号小团体的票数 。
输出
对每组测试数据 ,在同一个行按顺序输出1到n号小团体的权利指数 。
输入样例
2
1
10
7
5 7 4 8 6 7 5
输出样例
1
16 22 16 24 20 22 16
(1)编程思路 。
同样直接套用上面的二进制枚举的模板对n个小团体的各种组合情况进行处理 。若某个团体组合的得票数超过了总票数的一半 ,则依次对该组合中的每个小团队进行判断 ,若去掉了某个小团体后 ,得票数小于总票数的一半 ,则去掉的小团体就是关键加入者 ,进行计数 。
(2)源程序 。
#include <stdio.h>
#include <string.h>
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int a[21],key[21], ans[21];
memset(ans, 0, sizeof(ans));
int n,total = 0;
scanf("%d", &n);
int i;
for (i = 0; i < n; i++)
{
scanf("%d", &a[i]);
total += a[i];
}
total /= 2;
for (i = 1; i < 1 << n; i++) // 二进制枚举各团体组合
{
int j, k = 0, sum = 0;
for (j = 0; j < n; j++) // 遍历二进制的每一位
{
if (i & (1 << j)) // 判断二进制第j位是否为1
{
key[k++] = j; sum += a[j];
}
}
if (sum > total) // 如果团体的票数超过总票数的一半
{
for (j = 0; j < k; j++)
if (sum - a[key[j]] <= total) // 编号为key[j]的元素为 关键加入者
ans[key[j]]++;
}
}
printf("%d", ans[0]);
for (i = 1; i < n; i++)
printf(" %d", ans[i]);
printf("\n");
}
return 0;
}
将上面的源程序提交给 HDU题库 HDU 1557 权利指数(http://acm.hdu.edu.cn/showproblem.php?pid=1557) ,可以Accepted 。
【例3】目标和习惯
问题描述
小明有很多习惯 ,比如看电影 、听音乐 、玩电脑游戏和足球等等 。此外 ,他还有很多目标 ,因为不是每个习惯都有助于实现他的目标,他陷入了在目标和习惯之间做出选择的困境 。
现在 ,我们将一个习惯对每个目标的影响定义为向量 ,向量的元素是整数,例如。向量(100,90 ,-10,80)表示它对目标1有100分的影响 ,对目标2有90分的影响、对目标3有-10分的影响和对目标4有80分的影响(正表示良好效果 ,负表示不良效果) ,每个目标的给定要求表示为整数 。请帮助小明实现他的目标 ,并尽可能多地保持他的习惯 。
输入
有多种情况 ,读取数据直到EOF。(不超过10例)
第1行:小明的目标数N(0<N<=20)
第2行:每个目标的要求(0<w<=1000)
第3行:小明的习惯数M(0<M<=16)
第4-M+4行:每行包含N个整数 ,第i个整数表示对第i个目标的影响(-1000<=data<=1000) 。
输出
对于每种情况:输出是一行 ,其中包含:
小明可以保持的最大习惯数 ,其次是:
小明可以保持的习惯的排序列表(从最小到最大) 。如果有一组以上的习惯可以满足要求 ,请选择习惯数最少的一组 。
如果无法实现小明的目标 ,请输出0 。
输入样例
4
100 200 300 400
3
100 100 400 500
100 -10 50 300
100 100 -50 -50
输出样例
2 1 3
(1)编程思路 。
采用二进制枚举对m个习惯的全部组合情况进行处理 。对每种习惯组合 ,将组合中的各习惯对目标的影响累加到数组g中 。若数组g中每个目标均可实现,则是一种满足要求的习惯组合 。
(2)源程序 。
#include <stdio.h>
#include <string.h>
int main()
{
int goal[21];
int f[17][21],g[21];
int n;
while (scanf("%d",&n)!=EOF)
{
int ans1=-1,ans2;
int i,j,k;
for (i=0;i<n;i++)
scanf("%d",&goal[i]);
int m;
scanf("%d",&m);
for (i=0;i<m;i++)
for(j=0;j<n;j++)
scanf("%d",&f[i][j]);
for (i=0;i<(1<<m);i++) // 对所有m个习惯的组合进行枚举
{
for (k=0;k<n;k++) g[k]=0; // 各目标的达到值初始化为0
int num=0; // 当前组合中的习惯个数
for (j=0;j<m;j++)
if (i&(1<<j)) // 若组合中有第j个习惯
{
num++;
for (k=0;k<n;k++) // 第j个习惯对每个目标k的影响
g[k]+=f[j][k];
}
for (k=0;k<n;k++)
if (g[k]<goal[k]) break; // 第k个目标不能实现
if (k==n) // 当前习惯组合中 ,所有目标可达成
{
if (num>ans1) { ans1=num; ans2=i; }
}
}
if (ans1==-1)
printf("0\n");
else
{
printf("%d",ans1);
for (i=0;i<n;i++)
if (ans2&(1<<i))
printf(" %d",i+1);
printf("\n");
}
}
return 0;
}
将上面的源程序提交给 HDU题库 HDU 4152 ZZY’s Dilemma(http://acm.hdu.edu.cn/showproblem.php?pid=4152) ,可以Accepted 。
【例4】调查问卷
问题描述
度度熊为了完成毕业论文,需要收集一些数据来支撑他的论据 ,于是设计了一份包含 m 个问题的调查问卷 ,每个问题只有 A 和 B 两种选项 。
将问卷散发出去之后 ,度度熊收到了 n 份互不相同的问卷 ,在整理结果的时候 ,他发现可以只保留其中的一部分问题 ,使得这 n 份问卷仍然是互不相同的 。这里认为两张问卷是不同的 ,当且仅当存在至少一个被保留的问题在这两份问卷中的回答不同。
现在度度熊想知道 ,存在多少个问题集合 ,使得这 n 份问卷在只保留这个集合的问题之后至少有 k 对问卷是不同的 。
输入
第一行包含一个整数 T ,表示有 T 组测试数据 。
接下来依次描述 T 组测试数据。对于每组测试数据:
第一行包含三个整数 n ,m 和 k ,含义同题目描述 。
接下来 n 行,每行包含一个长度为 m 的只包含 A 和 B 的字符串 ,表示这份问卷对每个问题的回答 。
保证 1≤T≤100 ,1≤n≤103,1≤m≤10 ,1≤k≤106 ,给定的 n 份问卷互不相同 。
输出
对于每组测试数据 ,输出一行信息 "Case #x: y"(不含引号) ,其中 x 表示这是第 x 组测试数据 ,y 表示满足条件的问题集合的个数 ,行末不要有多余空格 。
输入样例
2
2 2 1
AA
BB
2 2 2
AA
BB
输出样例
Case #1: 3
Case #2: 0
(1)编程思路 。
先把每张问卷对10个问题回答的A 、B字符串转换成二进制数保存在数组a中 ,转换时 ,A转换为1 ,B转换为0 。
采用二进制枚举的方法依次枚举每个可能的子集(选择部分问题的情况 ,下面将枚举到的某个二进制数i称为当前状态) ,与每张问卷的这个子集情况(当前状态i)下的答案匹配 。具体做法是:将当前状态i与每张试卷的答案(也已转换为了二进制数并保存在数据元素a[j]中)进行与运算 ,即now=i & a[j],并将cnt[now]加1 。显然 ,若问卷j和问卷k的答案相同 ,则a[j]与a[k]的值一定相同,这样now的值也相同 ,cnt[now]的值会加上2 。
当匹配到第j张问卷时 ,第j张问卷与前面的j-1张问卷在当前选择状态i下一定有cnt[i&a[j]]张(包括第j张)的答案相同 ,也就是有j- cnt[i&a[j]]张的答案存在不同 ,将它累加到和值sum上 。当某个当前状态i与每张问卷匹配完成后 ,如果和值sum大于或等于k ,这种当前状态 i 就是符合题意的一种子集选择 。遍历所有可能的子集 ,就得到最终的答案 。
(2)源程序。
#include <stdio.h>
#include <string.h>
int main()
{
int t,iCase=0;
scanf("%d",&t);
while (t--)
{
int n, m, k;
scanf("%d%d%d",&n,&m,&k);
int a[1001];
int i,j;
for (i=1; i<=n; i++)
{
char s[15];
scanf("%s",s);
int num=0;
for (j=0; s[j]!=\0; j++) // 第i张问卷对10个问题回答的A 、B字符串转换成二进制数保存在数组a[i]
{
if (s[j]==A)
num=num*2+1;
else num=num*2;
}
a[i] = num;
}
int ans = 0;
for (i=1; i<(1<<m); i++) // 对m个问题的全部组合情况进行枚举
{
int cnt[1050];
memset(cnt, 0, sizeof(cnt));
int sum = 0;
for (j=1; j<=n; j++)
{
int now = i & a[j];
cnt[now]++;
sum += j-cnt[now];
}
if(sum>=k) ans++;
}
printf("Case #%d: %d\n",++iCase,ans);
}
return 0;
}
将上面的源程序提交给 HDU题库 HDU 6344 调查问卷(http://acm.hdu.edu.cn/showproblem.php?pid=6344) ,可以Accepted 。
【例5】连续求余
问题描述
有一个整数a和n个整数b1 ,… ,bn 。在按任意顺序从b1、… 、bn中选择一些数字后 ,例如c1 、… 、cr ,我们希望确保a mod c1 mod c2 mod…mod cr=0(即,a将成为每次除以ci的余数 ,最后 ,我们希望a变为0)。请确定r的最小值 。如果无法实现目标,请输出−1代替 。
输入
第一行包含一个整数T≤5 ,表示测试用例的数量 。
对于每个测试用例 ,有两行:
第一行包含两个整数n和a(1≤n≤20,1≤a≤106) 。
第二行包含n个整数b1 ,… ,bn(1≤bi≤106)
输出
每个测试用例输出1行 ,该行中输出所求得的最小的r值 。
输入样例
2
2 9
2 7
2 9
6 7
输出样例
2
-1
(1)编程思路 。
采用二进制枚举的方法对b1 、… 、bn中的数的各种选择组合进行处理 。只是在本题处理时 ,需要先将数组b按从大到小的顺序进行排列 。因为 ,若先选择一个小的数进行求余 ,则后面较大的数的选择毫无意义 。
(2)源程序 。
#include <stdio.h>
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
int n,a,b[25]={0};
scanf("%d%d",&n,&a);
int i,j;
for (i=0;i<n;i++)
scanf("%d",&b[i]);
for (i=0;i<n-1;i++) // 将数组b按从大到小的顺序排列
for (j=0;j<n-1-i;j++)
if (b[j]<b[j+1])
{
int temp;
temp=b[j]; b[j]=b[j+1]; b[j+1]=temp;
}
int ans=25; // 所以数全部选 ,不会超过20个数
for (i=0;i<(1<<n);++i)
{
int res=a,cnt=0;
for (j=0;j<n;++j)
{
if(i>>j&1)
{
res=res%b[j];
cnt++;
if(res==0)break;
}
}
if (res==0)
ans=(cnt<ans)?cnt:ans;
}
if(ans==25) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}
将上面的源程序提交给 HDU题库 HDU 5339 Untitled(http://acm.hdu.edu.cn/showproblem.php?pid=5339) ,可以Accepted 。
在通过上面的5道例题的学习 ,掌握了二进制枚举方法的应用的基础上 ,可以刷一下HDU题库中的下面几道题目,也均可采用二进制枚举的方法来完成 。
【练习1】HDU 1882 Strange Billboard (http://acm.hdu.edu.cn/showproblem.php?pid=1882)。
#include <stdio.h>
#include <string.h>
int main()
{
int r,c;
while (scanf("%d%d",&r,&c)!=EOF)
{
if (r==0 && c==0) break;
int i,j,k;
char map[20][20],temp[20][20];
for (i=0;i<r;++i)
scanf("%s",map[i]);
if (r<c) // 若行数小于列数 ,则使矩阵转置 。
{
memcpy(temp,map,sizeof(map));
for (i=0;i<r;++i)
{
for (j=0;j<c;++j)
{
map[j][i]=temp[i][j];
}
}
k=r; r=c; c=k;
}
int hash[20],key[20];
for(i=0;i<r;++i) // 将第i行数据以二进制形式保存在数组元素hash[i]中 ,‘X’符号位置1
{
hash[i]=0;
for (j=0;j<c;++j)
{
if (map[i][j]==X)
hash[i]=(hash[i]<<1)^1;
else
hash[i]=(hash[i]<<1);
}
}
int ans=1000; // 按题意,最多256个方格 ,因此翻转次数肯定不会超过1000
for (i=0; i<(1<<c); i++) // 对第0行的所有翻转组合进行二进制枚举
{
int cnt=0;
memcpy(key,hash,sizeof(hash)); // 将初始画面情况数组hash暂存到key数组中
for (j=0;j<c;j++) // 处理第0行(首行)
{
if (i & (1<<(c-1-j)))
{
key[0]^=(1<<(c-1-j)); // 当前方块翻转
if (j-1>=0) // 当前方块左边(前一列)的方块翻转
key[0]^=(1<<(c-1-j+1));
if (j+1<c) // 当前方块右边(后一列)的方块翻转
key[0]^=(1<<(c-1-j-1));
if (1<r) // 当前方块下方(下一行)的方块翻转
key[1]^=(1<<(c-1-j));
cnt++; // 翻转次数加1
}
}
for (j=1;j<r;++j) // 上1行确定了 ,下一行只能根据上一行进行处理 。依次处理后面的r-1行
{
for (k=0;k<c;++k) // 对当前行的每列的方块进行判断 ,根据正上方的方块状态看是否需要翻转
{
if (key[j-1]&(1<<(c-1-k))) // 当前方块正上方方块为X‘ ,需要翻转当前方块
{
cnt++;
key[j]^=(1<<(c-1-k)); // 当前方块翻转
if (k-1>=0) // 当前方块左边(前一列)的方块翻转
key[j]^=(1<<(c-1-k+1));
if (k+1<c) // 当前方块右边(后一列)的方块翻转
key[j]^=(1<<(c-1-k-1));
if (j-1>=0) // 当前方块上方(上一行)的方块翻转
key[j-1]^=(1<<(c-1-k));
if (j+1<r) // 当前方块下方(下一行)的方块翻转
key[j+1]^=(1<<(c-1-k));
}
}
}
if (!key[r-1]) // 由于下一行必受上一行约束,则只要判断最后行是否达到要求即可
{
if (ans>cnt) ans=cnt;
}
}
if (ans<1000)
printf("You have to tap %ld tiles.\n",ans);
else
printf("Damaged billboard.\n");
}
return 0;
}
参考源程序
【练习2】HDU 3118 Arbiter (http://acm.hdu.edu.cn/showproblem.php?pid=3118)。
#include <stdio.h>
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
int n,m;
scanf("%d%d",&n,&m);
int map[305][2];
int i,j;
for (i=0;i<m;i++)
{
scanf("%d%d",&map[i][0],&map[i][1]);
}
int ans=0x3f3f3f3f;
for (i=0;i<(1<<n);i++)
{
int cnt=0;
for (j=0;j<m;j++)
{
if (((i>>map[j][0]) & 1)==((i>>map[j][1])&1))
cnt++;
}
if (cnt<ans) ans=cnt;
}
printf("%d\n",ans);
}
return 0;
}
参考源程序
【练习3】 HDU 4462 Scaring the Birds (http://acm.hdu.edu.cn/showproblem.php?pid=4462) 。
#include <stdio.h>
#include <string.h>
int abs(int x)
{
return x>0?x:-x;
}
int main()
{
int n;
while (scanf("%d", &n) && n!=0)
{
int m;
scanf("%d", &m);
int i,j;
int r[51],c[51],f[51];
for (i = 0; i < m; i++)
scanf("%d%d", &r[i], &c[i]);
for (i = 0; i < m; i++)
scanf("%d", &f[i]);
int ans = 100;
for (i = 0; i < (1 << m); i++) // 二进制枚举各位置放置稻草人的组合情况
{
int num = 0; // 放稻草人的个数
int a[10],vis[51][51];
memset(vis, 0, sizeof(vis));
for (j = 0; j < m; j++)
if (i&(1 << j))
a[num++] = j; // 保存所放稻草人的编号
int flag = 1;
int x,y,z;
for (x = 1; x <= n; x++) // 放置了num个稻草人后 ,看稻田所有位置是否全部覆盖
{
for (y = 1; y <= n; y++)
{
for (z = 0; z < m; z++)
if (r[z] == x && c[z] == y)
vis[x][y] = 1;
if (vis[x][y])
continue;
for (z = 0; z < num; z++)
{
if (abs(x - r[a[z]]) + abs(y - c[a[z]]) <= f[a[z]])
{
vis[x][y] = 1;
break;
}
}
if (vis[x][y] == 0) // 当前位置(x,y)不能覆盖
flag = 0;
if (!flag)
break;
}
if (!flag)
break;
}
if (flag)
if (ans>num) ans=num;
}
if (ans == 100)
printf("-1\n");
else
printf("%d\n", ans);
}
return 0;
}
参考源程序
【练习4】HDU 5616 Jams balance(http://acm.hdu.edu.cn/showproblem.php?pid=5616) 。
#include <stdio.h>
#include <string.h>
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
int vis[2005];
memset(vis,0,sizeof(vis));
int n;
scanf("%d",&n);
int i,j,a[21];
for (i=0; i<n; i++)
scanf("%d",&a[i]);
for (i=0; i<(1<<n); i++) // 二进制有n位 ,枚举二进制数
{
int sum=0; // 当前砝码组合可称出的总重量
for (j=0; j<n; j++)
{
if (i&(1<<j))
sum+=a[j];
}
vis[sum]=1;
for (j=0; j<n; j++) // 将每个砝码放在天平另一边
{
if (sum-a[j]>=0)
vis[sum-a[j]]=1;
}
}
int m,x;
scanf("%d",&m);
while (m--)
{
scanf("%d",&x);
if (vis[x]) printf("YES\n");
else printf("NO\n");
}
}
return 0;
}
参考源程序
【练习5】HDU 6435 Problem J. CSGO (http://acm.hdu.edu.cn/showproblem.php?pid=6435) 。
#include <stdio.h>
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
int n,m,K;
scanf("%d%d%d",&n,&m,&K);
long long mw[35],sw[35]; // K最大为5,2^5=32 。性能组合情况不超过32种
int i,j,k;
for (i=0;i<32;i++)
mw[i] = sw[i] = -1e16; // 为求最大值 ,主 、副武器的每种性能组合情况均预置一个很小的数
int s,x[6];
long long ret;
for (i=0;i<n;i++) // 依次处理每个主武器
{
scanf("%d",&s);
for (j=0;j<K;j++)
scanf("%d",&x[j]);
for (j=0;j<(1<<K);j++) // 对当前主武器的性能组合进行二进制枚举
{
ret = s;
for (k=0;k<K;k++)
ret += x[k]*((1&(j>>k))?1:-1);
if (mw[j]<ret) mw[j]=ret;
}
}
for (i=0;i<m;i++) // 依次处理每个副武器
{
scanf("%d",&s);
for (j=0;j<K;j++)
scanf("%d",&x[j]);
for (j=0;j<(1<<K);j++) // 对当前副武器的性能组合进行二进制枚举
{
ret = s;
for (k=0;k<K;k++)
ret += x[k]*((1&(j>>k))?1:-1);
if (sw[j]<ret) sw[j]=ret;
}
}
long long ans = 0;
for (i=0;i<(1<<K);i++)
{
ret=mw[i]+sw[(1<<K)-1-i]; // 主 、副武器二进制位要求互补
if (ans<ret) ans=ret;
}
printf("%lld\n",ans);
}
return 0;
}
参考源程序
声明:本站所有文章 ,如无特殊说明或标注 ,均为本站原创发布 。任何个人或组织 ,在未征得本站同意时 ,禁止复制 、盗用 、采集 、发布本站内容到任何网站 、书籍等各类媒体平台 。如若本站内容侵犯了原著者的合法权益 ,可联系我们进行处理 。