10.7

 不到90min的一场模拟赛

人挂掉了、

 

T1:

[USACO18DEC]Convention II S

 我是伞兵

 

#include<bits/stdc++.h>

using namespace std;
const int N=100005;

int n,flag,ans;
struct node
{
    int a,t,id,ed;
    bool operator <(const node x)const
    {
    if(x.a<a)
        return 0;
    if(x.a==a)    
        return x.id>id;    
    if(x.a>a)
        return 1;
    }
}a[N];

int x;
priority_queue< pair <int,int >  > q ;

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].a>>a[i].t;
        a[i].id=i;
    }
    sort(a+1,a+1+n);

    flag=a[1].a+a[1].t;
    
    for(int i=2;i<=n;i++)
    {
        if(a[i].a>=flag)
        {
            if(!q.empty())
            {
                x=q.top().second;
                q.pop();
                
                ans=max(ans,flag-a[x].a);
                flag+=a[x].t;
                
                if(flag<a[i].a)
                i--;
                else            
                q.push({-a[i].id,i});
            }
            else
                flag=a[i].a+a[i].t;
        }
        else
        {
            q.push({-a[i].id,i});
        }
    }
    
    while(!q.empty())
    {
        x=q.top().second;
        q.pop();
        
        ans=max(flag-a[x].a,ans);
        flag+=a[x].t;
    }
    
    cout<<ans;
    return 0;
}

 

 

T2:

[USACO4.1]麦香牛块Beef McNuggets

非同余最短路做法:dp

我们可以想到一个很暴力的状态,即:$ dp[i] $ 表示 $ i $ 可否能被‘拼’出来

我们可以像dp(背包)一样来考虑这个状态转移 

$ dp[ j ] =dp[j] || dp[j-a[i]] $ 

但是:这个数据还大,2e9的数据大小连桶都开不下。很明显,要么不是一个一个枚举,要么就是有一个上下界

可惜考场上推了半天,没出来上界

--------

每个元素最大为256,如果集合大小为2且二者互质,则答案为 $ (a*b-a-b) $ .

那么我们来考虑极端情况,借此去考虑上界。

假设我们有256,255,二者互质这个情况为max,那么我们就可得256*255-256-255

但是N的范围是50啊~~~一个集合中元素越少(在上述的情况,并非gcd(all)>1的0的情况),那么它所不能拼出的数字就越多,所对最大不能拼出的数字就越大。

 由此上界可得,证毕

#include<bits/stdc++.h>

#define int long long
using namespace std;
const int inf=256*256-2*256+1;

int n;
bool dp[inf<<1];
int a[55];
int ans;

signed main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    
    dp[0]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=a[i];j<=inf;j++)
        {
            dp[j]=dp[j]||dp[j-a[i]];    
        }
    }
    
    for(int i=inf;i;i--)
    {
        if(!dp[i])
        {
            ans=i;
            break;
        }
    }
    if(ans>65024)
    cout<<0;
    else
    cout<<ans;
    
    
    return 0;
}

 

 

 T3:

CF1110C Meaningless Operations

求  

$ f(a)=\max_{0<b<a} gcd(a \oplus b ,a \& b ) $

考场上审错题了

我们可以打个表,不难发现是二进制题;打表发现如果一个数字的二进制不全是一,那这个数字就是他的二进制填满1、

如果它是某一个2^()的形式,那么就去找它的约数们,那个最大不等于它本身的约数

可以用log来判断他在表中的那两个区间

#include<bits/stdc++.h>

#define int long long
using namespace std;

int q;
int n;
int x;
int a[33]={1,1,5,1,21,1,85,73,341,89,1365,1,5461,4681,21845,1,87381,1,349525,299593,1398101,178481,5592405,1082401,22369621,1};

signed main()
{
    ios::sync_with_stdio(false);
    cin>>q;
    
    while(q--)
    {
        cin>>n;    
        x=n;
        if(n==3)
        {
            cout<<1<<endl;
            continue;
        }
        if(!(x&(x+1)))
        {
            int num=log2(n)-1;
            cout<<a[num]<<endl;
        }
        else
        {
            int num=0;
            while(x)
            {
                x>>=1;
                num++;
            }
            int f=1,p=1;
            for(int i=1;i<=num;i++)
            {
                f<<=1;
            }
            cout<<(f-1)<<endl;
        }
    }
    
    return 0;
}

 

 

 

 T4:

 

 

posted @ 2021-10-08 10:18  Hehe_0  阅读(129)  评论(0)    收藏  举报