1. 程式人生 > >杭電2018多校第四場(2018 Multi-University Training Contest 4) 1004.Problem D. Nothing is Impossible (HDU6335) -思維題

杭電2018多校第四場(2018 Multi-University Training Contest 4) 1004.Problem D. Nothing is Impossible (HDU6335) -思維題

假設 spa 。。 lan 多校 () class span tdi

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 }

心情不爽,就這樣。

杭電2018多校第四場(2018 Multi-University Training Contest 4) 1004.Problem D. Nothing is Impossible (HDU6335) -思維題