题目链接:https://codeforces.com/gym/102220/problem/B
说题解之前,因为TL很多次,说说cin的加速和scanf。
std::ios::sync_with_stdio(0);来加速cin 与cout ,这样cin的速度就和sanf差不多了,
注意,这两个代码的头文件是 iostream
并且如果用了这两个,就不要用scanf ,getchar,gets,fgets,fscanf了,
他的作用是关于 iostream和stdio的同步,让c++和c的输入出不在挂钩了(具体原理我也不清楚哈)
还有就是,用“\n”而不是 endl,也可以提高速度。
自己好菜呀!这个题意读了好久才明白。先是给你一个数 T 有T组数据! 每组数据 给了 N和M表示有M种类型的糖果,这些糖果一共N个。 接下了是 M 组数据,表示如果你选第 i 中糖果,那么你最少选 Li (你也可以不选), 再接下来就是 N 行数据,每一行 ai 和 bi 表示这个糖果属于 bi 这个种类的,它的价值是ai。 最后让你输出你挑选的糖果的总价值除以 你取得糖果中数量最多的那种糖果的数量,然后化成最简分数, 比如说 第 1 种你取了 2 个,第 2 中你取了 4 个,第三种你取了 1 个,那么分母就是 4 了。
相比读题的苦苦挣扎,解题就好受多了,既然我们要选出的分数最大,那么我们就可以直接暴力的去比较,从最多选一个,然后两个,这样我们遍历一遍就好了,从前向后开始遍历的时候,我们可以提前预处理一下,将每种没类型的的糖果的价值从大到小进行排序,然后遍历到几选的时候就可以直接选了前几个就行了,用一个vector数组,进行储存选几的时候sum和是多少。(注意我们不能直接找出最多要选的数量,然后每种都选前 相应 的数量的价值数,因为可能这种类型的糖果我们可以不选)说的有点复杂还是直接看代码吧!
附带两份代码
#include<bits/stdc++.h> using namespace std; typedef long long ll; vector<int>ve[100009],vec[100009]; int a[100009]; bool cmp(int x,int y) { return x>y; } int main() { int t,n,m,x,y; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d",&a[i]); for(int i=0;i<n;i++) { scanf("%d%d",&x,&y); ve[y].push_back(x); } for(int i=1;i<=m;i++){ sort(ve[i].begin(),ve[i].end(),cmp); for(int j=0;j<ve[i].size();j++){ vec[max((j+1),a[i])].push_back(ve[i][j]); } ve[i].clear(); } ll S=0,C=1,s=0,c; for(int i=1;i<=n;i++){ c=i; for(int j=0;j<vec[i].size();j++){ s+=vec[i][j]; } if(S*c<s*C){ S=s; C=c; } vec[i].clear(); } ll k=__gcd(S,C); printf("%lld/%lld\n",S/k,C/k); } return 0; }