《牛客直播课习题1》

前言:随缘更新,水题不写.

题目:奇♂妙拆分

思路:

很显然是个质因子分解的思路。

map统计下没被分解过的因子即可.

Code:

#include<iostream>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<math.h>
#include<stack>
#include<map>
#include<limits.h>
#include<vector>
#include<string.h>
#include<string>
using namespace std;
typedef long long LL;
typedef pair<double,double> pii;
const int N = 5e5+5;
const int M = 1005;
const int Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e8
#define INM INT_MIN
#define pb(a)  push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
int main()
{
    int t;sd(t);
    while(t--)
    {
        int n;sd(n);
        int m = sqrt(n),ans = 1;
        map<int,int> mp;
        mp[1]++;
        for(int i=2;i<=m;++i)
        {
            if(n == 1) break;
            if(n%i == 0 && mp[i] == 0)
            {
                mp[i]++;ans++;
                n /= i;
            }
        }
        if(mp[n] == 0) ans++;
        pr(ans);
    }
   // system("pause");
    return 0;
}
View Code

 题目:国王的游戏

思路:

贪心证明:
对于相邻的两个人A,B.
他们两个人之间的交换对A,B前面的人和A,B后面的人无影响.
所以从相邻的两人入手.
定义一个人的队列为[Q,W,E,R..,A,B,....].
令A,B前面的人的左手乘积为sum1.
那么如果选A排在前面,ans = max(sum1/b[A],sum1*a[A]/b[B]).
如果选B排在前面,ans = max(sum1/b[B],sum1*a[B]/b[A]).
很显然从上述两个ans式子可以发现:
sum1/b[A] <= sum1*a[B]/b[A].
sum1/b[B] <= sum1*a[A]/b[B].
如果A排在前面更优.
那么sum1*a[B]/b[A] > sum1*a[A]/b[B]. -> a[B]/b[A] > a[A]/b[B].
乘底数之积之后变为,a[B]*b[B] > a[A]*b[A].
如果B排在前面更优。
那么同理推得a[A]*b[A] > a[B]*b[B].

那么可知排在前面的数乘积应该尽可能小.
结论:按乘积从小到大排序..
Code:
#include<bits/stdc++.h>
using namespace std;
#define INF INT_MAX
#define INM INT_MIN
typedef long long LL;
typedef pair<int,int> pii;
const int N = 1e4+5;
int ans[N],sum[N] = {0,1},last[N] = {0,1},len1 = 1,len2 = 1,lenla = 1;
struct Node
{
    int x,y;
    LL add;
}p[N];
bool cmp(Node a,Node b)
{
    return a.add < b.add;
}
void bigc(int x)
{
    int tmp = 0;
    for(int i=1;i<=len1;++i)
    {
        sum[i] *= x;
    }
    for(int i=1;i<=len1;++i)
    {
        tmp += sum[i];
        sum[i] = tmp%10;
        tmp /= 10;
    }
    while(tmp != 0)//位数增加
    {
        len1++;
        sum[len1] = tmp%10;
        tmp /= 10;
    }
}
void divition(int x)
{
    memset(ans,0,sizeof(ans));
    int tmp = 0;
    len2 = len1;
    for(int i=len1;i>=1;--i)//从高位开始,保证tmp不会太大,从而完成模拟
    {
        tmp *= 10;//模拟除法
        tmp += sum[i];
        if(tmp >= x)//可以除了
        {
            ans[i] = tmp/x;//这里是除去,不再是取余了,因为是除法..
            tmp %= x;
        }
    }
    while(ans[len2] == 0)//去除前缀0
    {
        if(len2 == 1) break;//本身为1时
        len2--;
    }
}
void Compare()
{
    if(len2 > lenla)//大,要交换
    {
        for(int i=1;i<=len2;++i)
        {
            last[i] = ans[i];
        }
        lenla = len2;//长度也要变
    }
    else if(len2 == lenla)
    {
        for(int i=len2;i>=1;--i)//从高位开始比较
        {
            if(ans[i] > last[i])
            {
                for(int j=1;j<=len2;++j)
                {
                    last[j] = ans[j];
                }
                lenla = len2;
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin >> n >> p[0].x >> p[0].y;
    for(int i=1;i<=n;++i)
    {
        cin >> p[i].x >> p[i].y;
        p[i].add = p[i].x*p[i].y;
    }
    sort(p+1,p+n+1,cmp);
    for(int i=1;i<=n;++i)
    {
        bigc(p[i-1].x);
        divition(p[i].y);
        Compare();
    }
    for(int i=lenla;i>=1;--i) cout << last[i];
    cout << endl;
}
View Code

 题目:校门外的树:

解法1:直接上线段树.

Code:

#include<iostream>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<math.h>
#include<stack>
#include<map>
#include<limits.h>
#include<vector>
#include<string.h>
#include<string>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> pii;
const int N = 3e4+5;
const int M = 1005;
const int Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e8
#define INM INT_MIN
#define pb(a)  push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
struct Node{int L,r,val,tag;}node[N<<2];//val记录树的个数,0-没砍,1-砍了.
void Pushup(int idx){node[idx].val = node[idx<<1].val+node[idx<<1|1].val;}
void Pushdown(int idx)
{
    if(node[idx].tag == 1)
    {
        node[idx<<1].val = node[idx<<1|1].val = 0;
        node[idx<<1].tag = node[idx<<1|1].tag = 1;
        node[idx].tag = 0;
    }
}
void build(int L,int r,int idx)
{
    node[idx].L = L,node[idx].r = r,node[idx].tag = 0;
    if(L == r) 
    {
        node[idx].val = 1;
        return ;
    }
    int mid = L+r>>1;
    build(L,mid,idx<<1);build(mid+1,r,idx<<1|1);
    Pushup(idx);
}
void update(int L,int r,int idx)
{
    if(node[idx].L >= L && node[idx].r <= r) node[idx].val = 0,node[idx].tag = 1;
    else
    {
        int mid = node[idx].L+node[idx].r>>1;
        Pushdown(idx);
        if(mid >= L) update(L,r,idx<<1);
        if(mid < r) update(L,r,idx<<1|1);
        Pushup(idx);
    }
}
int query(int L,int r,int idx)
{
    if(node[idx].L >= L && node[idx].r <= r) return node[idx].val;
    int mid = node[idx].L+node[idx].r>>1,ans = 0;
    Pushdown(idx);
    if(mid >= L) ans += query(L,r,idx<<1);
    if(mid < r) ans += query(L,r,idx<<1|1);
    return ans;
}
int main()
{
    int L,m;sdd(L,m);
    build(0,L,1);
    while(m--)
    {
        int x,y;sdd(x,y);
        update(x,y,1);
    }
    int ans = query(0,L,1);
    pr(ans);
    //system("pause");
    return 0;
}
View Code

解法2:差分.

这里有重复的,但是要明白差分是不会影响到差分那段之外的。

只会让原来的那段更大而已。那么就很简单了。如果某段砍去,那就让这段里的树都加上1.

如果有重复,那只会>1.所以我们只需要统计0的个数,就是还在的树.

Code:

#include<iostream>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<math.h>
#include<stack>
#include<map>
#include<limits.h>
#include<vector>
#include<string.h>
#include<string>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> pii;
const int N = 3e4+5;
const int M = 1005;
const int Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e8
#define INM INT_MIN
#define pb(a)  push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
int s[N];
int main()
{
    int L,m;sdd(L,m);
    while(m--)
    {
        int x,y;sdd(x,y);
        s[x]++,s[y+1]--;
    }
    for(int i=0;i<=L;++i) s[i] += s[i-1];
    int ans = 0;
    for(int i=0;i<=L;++i) if(s[i] <= 0) ans++;
    pr(ans);
  //  system("pause");
    return 0;
}
View Code

题目:拼数

思路:贪心。

证明:

可以将每个数看成一个字符串。那么对于最终的答案,就是求字典序最大的数(这里的字典序大定义为数大.不是abcd那种).

那么先从相邻的两个字符串s1,s2入手。

我们按照s1+s2  和  s2+s1里较大的那个排序,求得了这两个字符相连后的较大的字典序.

那么这样映射到全局,对于所有的相邻的,都按照这样的思路来排序,就能使得所有的相连后的字典序最大.

Code:

#include<iostream>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<math.h>
#include<stack>
#include<map>
#include<limits.h>
#include<vector>
#include<string.h>
#include<string>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> pii;
const int N = 3e4+5;
const int M = 1005;
const int Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e8
#define INM INT_MIN
#define pb(a)  push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
bool cmp(string a,string b)
{
    return a+b > b+a;
}
int main()
{
    int n;sd(n);
    string s[20];
    for(int i=1;i<=n;++i) cin >> s[i];
    sort(s+1,s+n+1,cmp); 
    for(int i=1;i<=n;++i) cout << s[i];
   // system("pause");
    return 0;
}
View Code

.题目:Selfish Grazing

思路:贪心.

首先思考到当前的位置,右边界r肯定是要越小越好.

那么我让每一个的右边界都尽量小,可知按右边界从小到大排序为最优思路。

为什么不是按左边界?因为我们从头开始扫,对于当前的点能和一下产生矛盾的只有右边界。

如果从尾部开始扫的话,就可以按左边界排序.

Code:

#include<iostream>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<math.h>
#include<stack>
#include<map>
#include<limits.h>
#include<vector>
#include<string.h>
#include<string>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> pii;
const int N = 1e5+5;
const int M = 1005;
const int Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e8
#define INM INT_MIN
#define pb(a)  push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
struct Node{int L,r;}p[N];
bool cmp(Node a,Node b)
{
    if(a.r == b.r) return a.L > b.L;
    return a.r < b.r;
}
int main()
{
    int n;sd(n);
    for(int i=1;i<=n;++i) sdd(p[i].L,p[i].r);
    sort(p+1,p+n+1,cmp);
    int ans = 1,r = p[1].r;
    for(int i=2;i<=n;++i)
    {
        if(r <= p[i].L) ans++,r = p[i].r;
    }
    pr(ans);
    //system("pause");
    return 0;
}
View Code

 题目:值周

思路:

首先可以直接暴力差分,因为数据不够强..

我一开始的思路是将所有点排序后,按每段区间来离散化.

但是T了?复杂度算了下应该不会爆..不知道什么原因.

正解:离散化+差分.

因为L到达了1e8,但是m比较小。

所以可以离散化。

将每段区间按左边界从小到大,右边界从小到大排序。

用删树的思路。开始我们的值为所有的树.

然后从头开始遍历离散化后的区间

对于当前离散化到的区间。

假定为[L,r].

如果它的r > 下一个区间的r,那么在之前对[L,r]区间内的删边操作中,肯定已经将下一个区间里的树都删完了。

如果它的r < 下一个区间的r,那么说明区间内有没删的树。那么找到左边界max(p[i].L,la]。因为如果la > p[i].L,那么肯定要取la,这样保证不会重复删树.

然后删去p[i].r-l+1的树,然后r值继续推移到p[i].r+1,加1保证不会重复删.

Code:

#include<iostream>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<math.h>
#include<stack>
#include<map>
#include<limits.h>
#include<vector>
#include<string.h>
#include<string>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> pii;
const int N = 1e6+5;
const int M = 1005;
const int Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e8
#define INM INT_MIN
#define pb(a)  push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
inline int read()
{
    int x = 0,f = 1;char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}
    while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();}
    return x*f;
}
struct Node{int L,r;}p[N];
bool cmp(Node a,Node b)
{
    if(a.L == b.L) return a.r < b.r;
    return a.L < b.L;
}
int main()
{
    int L,m;
    L = read();m = read();
    for(int i=1;i<=m;++i)
    {
        p[i].L = read(),p[i].r = read();
    }
    sort(p+1,p+m+1,cmp);
    int ans = L+1,la = 0;
    for(int i=1;i<=m;++i)
    {
        if(la <= p[i].r)
        {
            int sl = max(p[i].L,la);
            ans -= p[i].r-sl+1;
            la = p[i].r+1;
        }
    }
    pr(ans);
    //system("pause");
    return 0;
}
View Code

 题目:切长条

思路:

贪心:
按尾部从小到大排序.
 
因为我们按尾部来排序,可以使得每次切尾部,尾部在我们之前的已经被处理好。
尾部在我们之后的且与我们有交集的,也会在这次尾部切时被计算在内.(画图更直观)
Code:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> pii;
const int N = 1e6+5;
const int M = 1005;
const int Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e8
#define INM INT_MIN
#define pb(a)  push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
struct Node{int L,r;}p[N];
bool cmp(Node a,Node b)
{
    if(a.L == b.L) return a.L < b.L;
    return a.r < b.r;
}
int main()
{
    int n;sd(n);
    for(int i=1;i<=n;++i) 
    {
        int x,y;sdd(x,y);
        p[i].L = x,p[i].r = p[i].L+y-1;//一个数字代表一个长度
    }
    sort(p+1,p+n+1,cmp);
    int ans = 1,lr = p[1].r;
    for(int i=2;i<=n;++i)
    {
        if(p[i].L > lr) ans++,lr = p[i].r;
    }
    pr(ans);
    //system("pause");
    return 0;
}
View Code

 题目:Flip Game

思路:

基本状压题.主要在于代码简化。

可以将查找函数写成两个字符串的形参形式来简化代码。

Code:

#include<iostream>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<math.h>
#include<stack>
#include<map>
#include<limits.h>
#include<vector>
#include<string.h>
#include<string>
using namespace std;
typedef long long LL;
typedef pair<double,double> pii;
const int N = 2e5+5;
const int M = 1e6+5;
const int Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e8
#define INM INT_MIN
#define pb(a)  push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
string mp[5];
char st[5][5];
int vis[5][5],ans = INF;//vis表示有没有翻转过.
void update_same(int i,char c1,char c2)//同一行内更新,c1-目标,c2-不满足的
{
    for(int j=0;j<4;++j)
    {
        int tmp = vis[i][j]+vis[i][j+1];
        if(j != 0) tmp += vis[i][j-1];
        if(i != 0) tmp += vis[i-1][j];
        tmp %= 2;
        if((st[i][j] == c1 && tmp == 0) || (st[i][j] == c2 && tmp == 1)) st[i][j] = c1;
        else st[i][j] = c2;
    }
}
bool check(int i,int j,char c1)
{
    if(st[i-1][j] == c1) return true;
    return false;
}
void slove(char c1,char c2)
{
    for(int i=0;i<(1<<4);++i)
    {
        int tmp = 0;
        for(int j=0;j<4;++j)
            for(int k=0;k<4;++k) st[j][k] = mp[j][k];
        met0(vis);
        for(int j=0;j<4;++j)
        {
            int sta = ((i>>j)&1);
            if(sta == 1) vis[0][j]++,tmp++;
        }
        update_same(0,c1,c2);
        for(int j=1;j<4;++j)
        {
            for(int k=0;k<4;++k)
            {
                if(!check(j,k,c1)) vis[j][k]++,tmp++;
            }
            update_same(j,c1,c2);
        }
        bool f = 0;
        for(int j=0;j<4;++j) if(st[3][j] != c1){f = 1;break;}
        if(!f) ans = min(ans,tmp);
    }
}
int main()
{
    for(int i=0;i<4;++i) cin >> mp[i];
    //全白
    slove('b','w');
    slove('w','b');
    if(ans == INF) printf("Impossible\n");
    else pr(ans);
 //   system("pause");
    return 0;
}
View Code

题目:「土」巨石滚滚

思路:

贪心策略:
当可以回馈>=消耗时,优先选择消耗小的.
当回馈都<消耗时时,优先选择回复多的.
其他的情况优先选择相对回复多的(即消耗-回复相对大的).
细节:m会爆int.
Code:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<double,double> pii;
const int N = 5e5+5;
const int M = 1e5+5;
const int Mod = 1e9+7;
#define pi acos(-1)
#define INF 1e8
#define INM INT_MIN
#define pb(a)  push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
struct Node{int a,b,c;}p[N];
bool cmp(Node a,Node b)
{
    if(a.c >= 0 && b.c >= 0) return a.a < b.a;
    else if(a.c < 0 && b.c < 0) return a.b > b.b;
    return a.c > b.c;
}
int main()
{
    int t;sd(t);
    while(t--)
    {
        int n,m;sdd(n,m);
        for(int i=1;i<=n;++i) 
        {
            sdd(p[i].a,p[i].b);
            p[i].c = p[i].b-p[i].a;
        }
        sort(p+1,p+n+1,cmp);
        LL tmp = m;
        bool f = 0;
        for(int i=1;i<=n;++i)
        {
            tmp -= p[i].a;
            if(tmp < 0) 
            {
                f = 1;
                break;
            }
            tmp += p[i].b;
        }
        if(f) printf("No\n");
        else printf("Yes\n");
    }
    system("pause");
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zwjzwj/p/12912689.html