CF1267E Elections

题目描述

有n(n<=100)个人,m(m<=100)个投票站,每个投票站对每个人都有一定的票数(<=1000).
第n个是坏蛋,请问去除掉哪几个投票站才能使他的票数严格小于其他每个人中的一个,也就是不能让第n个人的总票数最多。

输入格式

第一行是两个整数,分别是n和m.
接下来m行n列,代表每个投票站对这n个人的票数。

输出格式

第一行一个整数k,代表需要去掉几个投票站。
第二行有k个数,代表投票站的号数,不要求字典序.

贪心

问的是去除那几个投票站.

思路

先对每个人进行处理,使用一个结构体,存下每个投票站给他的票数和给第n个人的票数的差和投票站编号.在进行排序,差值从小到大,在倒序判断,加上当前的差值后总差值是否小于0,因为就算当前总差值小于0也可能在之后变为正,所以需要排序之后从大到小求和,如果当前已经为负了,就可以考虑去除这个投票站。因为只要有任意一个严格大于第n个就行了,所以取这n-1个人中需要去掉投票站最少的一个。此处可以用vector维护.

参考代码

#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const ll N=105;
int n,m;
struct node{
    int a;
    int b;
}brr[N];
bool comp(node x, node y){
    return x.a<y.a;
}
int arr[N][N];
vector<int> boy[N];
int main() {
    scanf("%d%d",&n,&m);
    for (int i=0;i<m;i++)
        for (int j=0;j<n;j++)
            scanf("%d",&arr[i][j]);
    for (int i=0;i<n-1;i++){
        for (int j=0;j<m;j++){
            brr[j].a=arr[j][i]-arr[j][n-1];
            brr[j].b=j;
        }
        sort(brr,brr+m,comp);
        int val=0;
        for ( int j=m-1;j>=0;j--)
            if (val+brr[j].a>=0)
                val+=brr[j].a;
            else
                boy[i].push_back(brr[j].b);
    }
    int min=0;
    for(int i=0;i<n-1;i++)
        min=boy[i].size()<boy[min].size()?i:min;
    printf("%d\n",boy[min].size());
    for(int i=0;i<boy[min].size();i++)
        printf("%d ",boy[min][i]+1);
    printf("\n");
}

猜你喜欢

转载自www.cnblogs.com/Fast-Bird/p/11972053.html
今日推荐