AtCoder Beginner Contest 318

目录

A - Full Moon

B - Overlapping sheets

C - Blue Spring

D - General Weighted Max Matching

E - Sandwiches

F - Octopus


A - Full Moon

#include
using namespace std;
const int N=1e6+5;
typedef long long ll ;
const int maxv=4e6+5;
typedef pair pll;
 


void solve()
{
    int n,m,p;
    cin>>n>>m>>p;
    if(m>n) cout<<0<>t;
    while(t--){
        solve();
    }
    system("pause");
    return 0;
}

B - Overlapping sheets

一眼扫描线,感觉人都魔楞了

#include
using namespace std;
const int N=1e6+5;
typedef long long ll ;
const int maxv=4e6+5;
typedef pair pll;
 
int st[105][105];

void solve()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        int a,b,c,d;
        cin>>a>>b>>c>>d;
        for(int l=a+1;l<=b;l++){
            for(int r=c+1;r<=d;r++){
                st[l][r]=1;
            }
        }
    }
    int cnt=0;
    for(int i=0;i<105;i++){
        for(int j=0;j<105;j++){
            if(st[i][j]) cnt++;
        }
    }
    cout<>t;
    while(t--){
        solve();
    }
    system("pause");
    return 0;
}

C - Blue Spring

思路:贪心,考虑购票乘车票的代价和直接购票的代价即可。

#include
using namespace std;
const int N=1e6+5;
typedef long long ll ;
const int maxv=4e6+5;
typedef pair pll;
 
int st[105][105];

void solve()
{
    int n,d,p;
    cin>>n>>d>>p;
    vector a(n+5),s(n+5);
    for(int i=1;i<=n;i++) cin>>a[i];
    sort(a.begin()+1,a.begin()+1+n,greater());
    for(int i=1;i<=n;i++){
        s[i]=s[i-1]+a[i];
    }
    ll ans=1e18;
    for(int i=1;i<=n;i++){
        ll t=(i+d-1)/d;
        ll v=t*p;
        if(v>t;
    while(t--){
        solve();
    }
    system("pause");
    return 0;
}

D - General Weighted Max Matching

思路:搜索,思路和全排列搜索比较类似。

#include
using namespace std;
const int N=1e6+5;
typedef long long ll ;
const int maxv=4e6+5;
typedef pair pll;
 

int n;

ll g[20][20];
int st[20];
ll res;
ll ans;
void dfs(int x)
{
    if(x>n){
        ans=max(ans,res);
        return ;
    }
    if(st[x]){
        dfs(x+1);
        return ;
    }
    for(int i=x+1;i<=n;i++){
        if(!st[i]&&!st[x]){
            st[i]=st[x]=1;
            res+=g[x][i];
            dfs(x+1);
            res-=g[x][i];
            st[i]=st[x]=0;
        }
    }
    dfs(x+1);
}



void solve()
{
    //int n;
    cin>>n;
    for(int i=1;i<=n-1;i++){
        for(int j=i+1;j<=n;j++){
            int w;
            cin>>w;
            //cout<>t;
    while(t--){
        solve();
    }
    system("pause");
    return 0;
}

E - Sandwiches

思路:因为要求a_ia_k相同,考虑a_j,使用桶去记录每个相同数字的下标,然后对每个数字进行枚举中间量a_j,对于中间量的枚举,如果我们对每个桶中的每个下标进行枚举,肯定会超时,考虑优化:我们发现,对于一个桶,我们计算到当前量j,那么其对答案的贡献为s_{j+1}-s_{j}+s_{j+2}-s_{j}+......+s_{s.size}-s_j,s表示a_j的个数,所以我们可以对这个前缀和再求一遍前缀和即可。

具体注释看代码。

#include
using namespace std;
const int N=1e6+5;
typedef long long ll ;
const int maxv=4e6+5;
typedef pair pll;
typedef array p3;
const int mod=1e9+7;


vector mp[N];


void solve()
{
    int n;
    cin>>n;
    ll res=0;
    vector a(n+5);
    for(int i=1;i<=n;i++){
        cin>>a[i];
        mp[a[i]].push_back(i);
    }
    for(int i=1;i<=n;i++){
        auto v=mp[i];
        vector b(v.size()+5),s(v.size()+5);
        for(int j=1;j ss(v.size()+5);
        for(int j=1;j>t;
    while(t--){
        solve();
    }
    system("pause");
    return 0;
}

F - Octopus

思路:对于一个位置k,我们考虑其是否合法,贪心的去想,我们将坐标和k的绝对值按升序排序,若每一个l_i能和排序后的x_i一一对应(即其都在l_i的那个区间内)。但因为k所能选的点的范围为1e18,我们不能去一一枚举,那么我们就考虑去寻找区间。

在寻找区间前,我们考虑当位于k时合法,位于k+1时不合法的情况,那么我们会发现仅有$k_0=X_i+L_j$符合条件。

同样,我们考虑位于k时不合法,位于k+1合法的情况,仅有$k_0=X_i-L_j-1$。符合条件。

所以我们一共会得到2*n*n个点,我们去检查每个点是否合法即可。

#include
using namespace std;
const int N=1e6+5;
typedef long long ll ;
const int maxv=4e6+5;
typedef pair pll;
typedef array p3;
const int mod=1e9+7;

int n;
vector x(205),l(205);

bool check(ll k)
{
    sort(x.begin()+1,x.begin()+1+n,[&](ll x,ll y){
        return abs(k-x)l[i]) return false;
    }
    return true;
}


void solve()
{
   // int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>x[i];
    }
    for(int i=1;i<=n;i++) cin>>l[i];
    vector s;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            s.push_back(x[i]+l[j]);
            s.push_back(x[i]-l[j]-1);
        }
    }
    sort(s.begin(),s.end());
    sort(l.begin()+1,l.begin()+1+n);
    ll ans=0;
    for(int i=1;i>t;
    while(t--){
        solve();
    }
    system("pause");
    return 0;
}

你可能感兴趣的:(补题记录,算法,数据结构)