HDU 6335.Problem D. Nothing is Impossible-思维题 (2018 Multi-University Training Contest 4 1004)
6335.Problem D. Nothing is Impossible
题意:给你n道题目,m个人,每题有x个正确选项,y个错误选项,问你做对题数量最多的人做对了多少道题目。
如果一道题有y个错误选项,那么我需要至少y+1个人才能保证一定有一个人做对了这道题目,所以题面上给的正确选项的数量x并没有什么实质性的作用。。。
假设第一题错误选项有y1个,第二题错误选项有y2个,那么怎么才能保证至少有一个人两道题目都做对了呢?
首先我需要至少y1+1个人才能保证一定有一个人做对了第一题,那么,我在做第二题的时候,我先让y1+1个人选了第一题,然后让他们都去选第二题的第一个错误选项,那么有一个人一定做对了一道题(第一题),然后我再让y1+1个人选了第一题之后都去选第二题的第二个错误选项,那么这y1+1个人里面也是一定有一个人做对了一道题,直到我把第二题的所有错误选项都让人选完之后,再来y1+1个人,我才能保证一定会有一个人两道题目都做对了,OK不?所以要保证一定有一个人两道题目都做对了,我需要(y1+1)*(y2+1)个人,才能保证一定有一个人两道题目都做对了。所以按照这个思路,一直到做第i个题目的时候,一定有一个人这I道题目都做对了,因为我需要最优情况,所以错误选项数量少的才能保证我做对的题目数量会多一些,所以直接对错误选项的数量进行排序,从小到大,就可以得到最多的做对题的数量。
语文不好,不知道解释的清不清楚。
官方题解:
直接代码吧:
1 //1004-6335-思维题 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<algorithm> 8 #include<queue> 9 #include<cassert> 10 using namespace std; 11 typedef long long ll; 12 const int maxn=100+10; 13 14 int a[maxn]; 15 16 int main() 17 { 18 int t; 19 scanf("%d",&t); 20 while(t--){ 21 int n,m; 22 scanf("%d%d",&n,&m); 23 memset(a,0,sizeof(a)); 24 for(int i=1;i<=n;i++){ 25 int x,y; 26 scanf("%d%d",&x,&y); 27 a[i]=y+1; 28 } 29 sort(a+1,a+1+n); 30 ll sum=1;int ans=0; 31 for(int i=1;i<=n;i++){ 32 sum*=a[i]; 33 if(sum<m) ans++; 34 else break; 35 } 36 printf("%d\n",ans); 37 } 38 }
心情不爽,就这样。