Winner Winner
题目描述
The FZU Code Carnival is a programming competetion hosted by the ACM-ICPC Training Center of Fuzhou University. The activity mainly includes the programming contest like ACM-ICPC and strive to provide participants with interesting code challenges in the future.
Before the competition begins, YellowStar wants to know which teams are likely to be winners. YellowStar counted the skills of each team, including data structure, dynamic programming, graph theory, etc. In order to simplify the forecasting model, YellowStar only lists M skills and the skills mastered by each team are represented by a 01 sequence of length M. 1 means that the team has mastered this skill, and 0 does not.
If a team is weaker than other teams, this team cannot be a winner. Otherwise, YellowStar thinks the team may win. Team A(a1, a2, ..., aM ) is weaker than team B(b1, b2, ..., bM ) if ∀i ∈ [1, M], ai ≤ bi and ∃i ∈ [1, M], ai < bi.
Since YellowStar is busy preparing for the FZU Code Carnival recently, he dosen’t have time to forecast which team will be the winner in the N teams. So he asks you to write a program to calculate the number of teams that might be winners.
输入
Input is given from Standard Input in the following format:
N M
s1 s2 . . . sN
The binary representation of si indicates the skills mastered by teami.
Constraints
1 ≤ N ≤ 2 × 106
1 ≤ M ≤ 20
0 ≤ si < 2M
输出
Print one line denotes the answer.
样例输入
3 3
2 5 6
样例输出
2
【题解】:
位运算的一个题目,题意是:有n个队伍,每一个能力根据n个队伍转化为01串后的,最大长度(01串)为m。
问题是:请找出能获胜的队伍,这个队伍的必须是别人不能把它干掉的。
什么意思呢?就是说如事例一样:
2 5 6
2:010
5:101
6:110
5 和 6 都不能相互干掉对方,以为他们的关系不是被包含。
2 被 6 干掉了。
2 因为缺乏第一种能力,能被6给代替。010,110
问题转化成:找出多少只队伍能够这些队伍中不能相互被包含,但是能把除去他们之外的队伍给包含。
用位运算再转化:
1、能够有机会获胜的队伍集合中,两两之间&运算,不能等于对方。
2、而不能获胜的队伍能被有机会获胜队伍集合中&运算等于自身。即被包含关系
代码思路是参考龙哥的代码的:Winter2121
#include<bits/stdc++.h>
using namespace std;
const int N = 4e6+100;
int vis[N],cnt[N];
int n,m,x,ans,f;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&x);
vis[x]=1;
cnt[x]++;
}
ans = n;
for(int i=(1<<(m))-1;i>=0;i--){
f = 0;
for(int j=0;j<m;j++){
if ( ((1<<j) & i) == 0){
if(vis[ ( i |(1<<j) ) ] ){
f=1;
vis[i] = 1;
}
}
}
if( f && cnt[i])
ans = ans - cnt[i];
}
printf("%d\n",ans);
return 0;
}
博客围绕FZU Code Carnival编程竞赛,YellowStar想预测获胜队伍。他统计各队技能,用01序列表示。题目要求找出不能被其他队“干掉”的队伍数量,可将问题转化为位运算问题,即找出队伍集合中两两间&运算不等于对方,且不能获胜队伍能被获胜队伍集合&运算等于自身的队伍数量。

1749

被折叠的 条评论
为什么被折叠?



