10.16互测题 贪心+数论

T1

题目链接:http://codevs.cn/problem/2913/

看题很容易想到贪心,

要么按修复时间(h)排序,要么按截止时间(t)排序,

那到底按什么呢?

我们挨个来试一下

假设我们用修复时间排序

但是有问题(QAQQQ)

现在修复时间已经是从小到大的了,

但修复时间不确定,

所以可能会出现之前h的和加上现在的h(啊好长QAQ),

大于现在的t的情况,

此时我们是丢掉这个不要么?

如果没有选择,那只能丢掉,

那这里的'选择'是什么呢?(啊好麻烦QAQ)

我们可以挑出已经选过的项目中t最大的,

和他换个位置?(想一想,可以么?)

举个例子;

3

100 100

200 750

500 700

然后你发现要是按上面说的操作,

也不能只是换个位子这么简单。。。

你还要考虑换位置后他和他前面的t的关系,

换过来的这个和之前的t的关系(感觉要疯。。。)

所以果断的抛弃以上做法(这么麻烦用他干嘛)

回到原点。。。按截止时间排序!

依然会有 ‘之前h的和加上现在的h大于现在的t’ 这种情况,

参照之前的思路,

从前面,

找一个h大于他的(比他更劣的)扔出去,

再把它放进去,

继续判断...

这样会不会有问题呢?

答案是不会,因为我们是按截止时间从小到大排的呀~

(既然之前那个更小的可以承载前面的,那么这个比他大的也一定可以)

哇。。。终于找到正解了!

之前说找那个替他出去的元素可以每次找最大,

然后堆优化,

这题就OK了。

然后在考场上困得要死。。一点耐心都没有QAQ。。。就挂掉了

Codes:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<queue>
 6 
 7 using namespace std;
 8 const int N = 150000 + 5;
 9 int n,ans;
10 struct zt{
11     int t,h;
12 }a[N];
13 priority_queue <int> q;
14 bool cmp(zt x,zt y){
15     return x.t < y.t;
16 }
17 int main(){
18     scanf("%d",&n);
19     for(int i = 1;i <= n;++ i){
20         scanf("%d%d",&a[i].h,&a[i].t);
21     }
22     sort(a + 1,a + 1 + n,cmp);
23     int tmp = 0;
24     for(int i = 1;i <= n;++ i){
25         tmp += a[i].h;
26         if(tmp > a[i].t){
27             int u = q.top();
28             if(u > a[i].h){
29                 q.pop();
30                 q.push(a[i].h);
31                 tmp -= u;
32             }
33             else{
34                 tmp -= a[i].h; 
35                 continue;
36             }
37         }
38         else {
39             q.push(a[i].h);
40             ans ++;
41         }
42     }
43     cout << ans << '
';
44     return 0;
45 }

 T4

题目链接:https://www.luogu.org/problem/show?pid=3927

在十进制下,2 * 5 = 10

在二进制下,1 * 2 = 2

在三进制下,1 * 3 = 3

在八进制下,2 * 4 = 8,2 * 2 * 2 = 8;

在十进制下我们要找2、5的个数,

相应的,

在k进制下,我们要找k的质因子的个数

取min,

不过要想办法优化时间,

这题就是这样。

Codes:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #define ll long long
 6 
 7 using namespace std;
 8 ll n,k,ans =0x7fffffffffffffffll;//9223372036854775807
 9 int main(){
10     while(scanf("%lld%lld",&n,&k)){
11     ans = 0x7fffffffffffffffll;
12         for(int i = 2;i * i <= k;++ i){
13             ll cnt = 0;
14             for(;k %i == 0;k /= i)
15                 cnt ++;
16             if(cnt == 0) continue; //不是k的质因子也不用分解n 
17             ll cnt1 = 0;
18             for(int j = i;j <= n; j *= i){
19                 cnt1 += n / j;
20             }
21             ans = min(ans,cnt1/cnt);
22         }
23         if(k != 1){
24             ll cnt = 0;
25             ll p = k;
26             while(k <= n){
27                 cnt += n / k;
28                 k *= p; 
29             }
30             ans = min(ans,cnt);
31         }
32         cout << ans << '
';
33     }
34     return 0;
35 }

 

 

原文地址:https://www.cnblogs.com/Loizbq/p/7677933.html