Atcoder Regular Contest 080 CDEF

轻量级分类讨论
#include <bits/stdc++.h>
using namespace std;
int n,cnt1,cnt2,cnt4,x;
int main()
{
    scanf("%d",&n);
    while (n--) {
        scanf("%d",&x);
        if (x%2!=0)
            ++cnt1;
        else if (x%4!=0)
            ++cnt2;
        else
            ++cnt4;
    }
    if (cnt1<=cnt4)
        puts("Yes");
    else if (cnt1>cnt4+1)
        puts("No");
    else if (cnt1==cnt4+1&&!cnt2)
        puts("Yes");
    else
        puts("No");
    return 0;
}
轻量级模拟
#include <bits/stdc++.h>
using namespace std;
int h,w,G[105][105],n;
priority_queue<int> que;
int main()
{
    scanf("%d%d%d",&h,&w,&n);
    for (int i=0;i<n;++i) {
        int t;
        scanf("%d",&t);
        while (t--)
            que.push(i+1);
    }
    for (int i=0;i<h;++i) {
        if (i&1) {
            for (int j=0;j<w;++j) {
                G[i][j]=que.top();
                que.pop();
            }
        } else {
            for (int j=w-1;j>=0;--j) {
                G[i][j]=que.top();
                que.pop();
            }
        }
    }
    for (int i=0;i<h;++i)
        for (int j=0;j<w;++j)
            printf("%d%c",G[i][j],j+1==w?'\n':' ');
    return 0;
}
倒推,维护区间偶数位置和奇数位置最小值
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
typedef pair<int,pii> pip;
const int maxn=200005;
int n,bit[maxn],a[maxn];
pii odd[20][maxn],even[20][maxn];
inline void init() {
    memset(odd,0x3f,sizeof odd);
    memset(even,0x3f,sizeof even);
    for (int i=1;i<=n;++i)
        if (i&1)
            odd[0][i]=pii(a[i],i);
        else
            even[0][i]=pii(a[i],i);
    for (int i=1;i<20;++i)
        for (int j=1;j+(1<<i)-1<=n;++j) {
            odd[i][j]=min(odd[i-1][j],odd[i-1][j+(1<<(i-1))]);
            even[i][j]=min(even[i-1][j],even[i-1][j+(1<<(i-1))]);
        }
}
inline pii oddmin(int l,int r) {
    int x=0;
    while ((1<<(x+1))<=r-l+1)
        ++x;
    return min(odd[x][l],odd[x][r-(1<<x)+1]);
}
inline pii evenmin(int l,int r) {
    int x=0;
    while ((1<<(x+1))<=r-l+1)
        ++x;
    return min(even[x][l],even[x][r-(1<<x)+1]);
}
priority_queue<pip,vector<pip>,greater<pip> > que;
vector<int> res;
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;++i)
        scanf("%d",&a[i]);
    init();
    que.push(pip(oddmin(1,n).first,pii(1,n)));
    while (!que.empty()) {
        int l=que.top().second.first,r=que.top().second.second;
        que.pop();
        pii p1,p2;
        if (l%2==0) {
            p1=evenmin(l,r);
            p2=oddmin(p1.second+1,r);
        } else {
            p1=oddmin(l,r);
            p2=evenmin(p1.second+1,r);
        }
        res.push_back(p1.first);
        res.push_back(p2.first);
        if (p1.second-1>=l)
            que.push(pip(l%2==1?oddmin(l,p1.second-1).first:evenmin(l,p1.second-1).first,pii(l,p1.second-1)));
        if (p1.second+1<=p2.second-1)
            que.push(pip((p1.second+1)%2==1?oddmin(p1.second+1,p2.second-1).first:evenmin(p1.second+1,p2.second-1).first,pii(p1.second+1,p2.second-1)));
        if (p2.second+1<=r)
            que.push(pip((p2.second+1)%2==1?oddmin(p2.second+1,r).first:evenmin(p2.second+1,r).first,pii(p2.second+1,r)));
    }
    for (int i=0;i<(int)res.size();++i)
        printf("%d%c",res[i],i+1==(int)res.size()?'\n':' ');
    return 0;
}
好题。用哥德巴赫猜想,转化成二分图最大匹配。
#include <bits/stdc++.h>
using namespace std;
const int maxn=105;
int n,a[maxn],cnt[2],match[maxn<<1];
bool used[maxn<<1];
vector<int> G[maxn<<1],diff;
set<int> vis;
bool dfs(int v) {
    used[v]=1;
    for (int i=0;i<(int)G[v].size();++i) {
        int u=G[v][i],w=match[u];
        if (w==-1||(!used[w]&&dfs(w))) {
            match[v]=u;
            match[u]=v;
            return true;
        }
    }
    return false;
}
inline int bipartite_matching() {
    int ret=0;
    memset(match,-1,sizeof match);
    for (int i=0;i<(int)diff.size();++i)
        if (diff[i]%2==1&&match[i]==-1) {
            memset(used,0,sizeof used);
            ret+=dfs(i);
        }
    return ret;
}
bool check(int x) {
    if (x<=2)
        return false;
    for (int i=2;i*i<=x;++i)
        if (x%i==0)
            return false;
    return true;
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;++i) {
        scanf("%d",&a[i]);
        vis.insert(a[i]);
    }
    for (int i=1;i<=n;++i) {
        if (vis.find(a[i]-1)==vis.end()) {
            diff.push_back(a[i]);
            ++cnt[a[i]%2];
        }
        if (vis.find(a[i]+1)==vis.end()) {
            diff.push_back(a[i]+1);
            ++cnt[(a[i]+1)%2];
        }
    }
    for (int i=0;i<(int)diff.size();++i)
        for (int j=i+1;j<(int)diff.size();++j)
            if (check(abs(diff[i]-diff[j]))) {
                G[i].push_back(j);
                G[j].push_back(i);
            }
    int k=bipartite_matching();
    printf("%d\n",k+2*((cnt[0]-k)/2+(cnt[1]-k)/2)+(cnt[0]-k)%2*3);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值