轻量级分类讨论
#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;
}