这题做的我好苦啊,编码调试整整搞了一个多小时,而且调到天昏地暗才调出来。。
回归正题,这题是一道本人做过的比较烦,比较无聊的题之一。题意是一个人,在m个影星里有k个喜欢的影星,然后给出n场电影,每场电影给出演出的人的编号,0表示不确定,根据这些人的编号判断是否一定是最喜欢的电影(喜欢的影星最多的电影),或者一定不会是最喜欢的电影,或者是不确定。
做法是算出每场电影最少有多少个喜欢的影星和最多有多少个喜欢的影星,并且得出在所有电影中最少有多少个喜欢的影星和最多有多少个喜欢的影星。
如果分别用MIN和MAX来表示,则有三种情况:
1.如果这场电影的MIN不小于任意一场电影的MAX,则这场电影必为最喜欢的电影。
2.如果这场电影的MAX不大于任意一场电影的MIN,则这场电影绝对不会是最喜欢的电影
3.介于两者之间
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <cstdlib> #include <string> #include <map> using namespace std; #define N 107 int zero[N],vis[N],a[N]; int d[N][N]; int like[N],mlike[N]; map<int,int> mp; int main() { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); int m,k,chang,i,j,maxilike,ka,maximlike; char ss[17]; while(scanf("%d%d",&m,&k)!=EOF) { mp.clear(); for(i=0;i<k;i++) { scanf("%d",&a[i]); //喜欢的影星编号 mp[a[i]] = 1; //看编号知是否喜欢的影星 } memset(zero,0,sizeof(zero)); maxilike = maximlike = -10000; scanf("%d",&chang); for(i=0;i<chang;i++) { scanf("%s",ss); scanf("%d",&ka); for(j=0;j<ka;j++) { scanf("%d",&d[i][j]); if(d[i][j] == 0) zero[i]++; } if(ka == m) { maxilike = max(maxilike,k); maximlike = max(maximlike,k); mlike[i] = k; like[i] = k; } else { int ca = 0; memset(vis,0,sizeof(vis)); for(j=0;j<k;j++) vis[a[j]] = 1; for(j=0;j<ka;j++) { if(mp[d[i][j]]) ca++; vis[d[i][j]] = 1; } int unvis = 0; for(j=1;j<=m;j++) { if(!vis[j]) unvis++; } if(unvis < zero[i]) { like[i] = ca + zero[i] - unvis; mlike[i] = ca + min(zero[i],k-ca); } else { mlike[i] = ca + min(zero[i],k-ca); like[i] = ca; } maxilike = max(maxilike,like[i]); maximlike = max(maximlike,mlike[i]); } } for(i=0;i<chang;i++) { if(like[i] >= maximlike || (like[i] >= maxilike && mlike[i] == maximlike)) { if(like[i] >= maximlike) printf("0 "); else { int flag = 1; for(j=0;j<chang;j++) { if(j!=i && like[i] < mlike[j]) { flag = 0; break; } } if(flag) printf("0 "); else printf("2 "); } } else if(mlike[i] < maxilike) printf("1 "); else printf("2 "); } } return 0; }