# AtCoder Regular Contest 080 [CDEF]

Time limit : 2sec / Memory limit : 256MB

## Problem Statement

We have a sequence of length N, a=(a1,a2,…,aN). Each ai is a positive integer.

Snuke's objective is to permute the element in a so that the following condition is satisfied:

For each 1≤i≤N−1, the product of ai and ai+1 is a multiple of 4.
Determine whether Snuke can achieve his objective.

## Constraints

2≤N≤105
ai is an integer.
1≤ai≤109

## Input

Input is given from Standard Input in the following format:

N
a1 a2 … aN

## Output

If Snuke can achieve his objective, print Yes; otherwise, print No.

Copy
3
1 10 100

## Sample Output 1

Copy
Yes
One solution is (1,100,10).

## 题解

4 = 2^2，那么我们把所有数分为奇数，偶数，4的倍数三种，最后的排列，我们贪心一下可以发现，只要所有偶数全部放在一起，然后奇数和4的倍数交叉放就行。

## 代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+7;
int flag[maxn];
int a[maxn];
int n;
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
cin>>a[i];
if(a[i]%4==0){
flag[2]++;
}else if(a[i]%2==0){
flag[1]++;
}else{
flag[0]++;
}
}
if(flag[1])flag[0]++;
if(flag[0]-1>flag[2]){
cout<<"No"<<endl;
}else{
cout<<"Yes"<<endl;
}
}

## D - Grid Coloring

Time limit : 2sec / Memory limit : 256MB

## Problem Statement

We have a grid with H rows and W columns of squares. Snuke is painting these squares in colors 1, 2, …, N. Here, the following conditions should be satisfied:

For each i (1≤i≤N), there are exactly ai squares painted in Color i. Here, a1+a2+…+aN=HW.
For each i (1≤i≤N), the squares painted in Color i are 4-connected. That is, every square painted in Color i can be reached from every square painted in Color i by repeatedly traveling to a horizontally or vertically adjacent square painted in Color i.
Find a way to paint the squares so that the conditions are satisfied. It can be shown that a solution always exists.

Constraints
1≤H,W≤100
1≤N≤HW
ai≥1
a1+a2+…+aN=HW

## Input

Input is given from Standard Input in the following format:

H W
N
a1 a2 … aN

## Output

Print one way to paint the squares that satisfies the conditions. Output in the following format:

c11 … c1W
:
cH1 … cHW
Here, cij is the color of the square at the i-th row from the top and j-th column from the left.

2 2
3
2 1 1

## Sample Output 1

1 1
2 3
Below is an example of an invalid solution:

1 2
3 1
This is because the squares painted in Color 1 are not 4-connected.

## 代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 105;
int mp[maxn][maxn];
int n,w,h,x,a[100005];
int main(){
scanf("%d%d",&h,&w);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
x=1;
for(int i=1;i<=h;i++){
if(i%2==1){
for(int j=1;j<=w;j++){
if(a[x]){
mp[i][j]=x;
a[x]--;
}else{
while(a[x]==0)x++;
mp[i][j]=x;
a[x]--;
}
}
}else{
for(int j=w;j>=1;j--){
if(a[x]){
mp[i][j]=x;
a[x]--;
}else{
while(a[x]==0)x++;
mp[i][j]=x;
a[x]--;
}
}
}
}
for(int i=1;i<=h;i++){
for(int j=1;j<=w;j++){
cout<<mp[i][j]<<" ";
}
cout<<endl;
}
}

## E - Young Maids

Time limit : 2sec / Memory limit : 256MB

## Problem Statement

Let N be a positive even number.

We have a permutation of (1,2,…,N), p=(p1,p2,…,pN). Snuke is constructing another permutation of (1,2,…,N), q, following the procedure below.

First, let q be an empty sequence. Then, perform the following operation until p becomes empty:

Select two adjacent elements in p, and call them x and y in order. Remove x and y from p (reducing the length of p by 2), and insert x and y, preserving the original order, at the beginning of q.
When p becomes empty, q will be a permutation of (1,2,…,N).

Find the lexicographically smallest permutation that can be obtained as q.

Constraints
N is an even number.
2≤N≤2×105
p is a permutation of (1,2,…,N).

## Input

Input is given from Standard Input in the following format:

N
p1 p2 … pN

## Output

Print the lexicographically smallest permutation, with spaces in between.

4
3 2 4 1

## Sample Output 1

3 1 2 4
The solution above is obtained as follows:

p q
(3,2,4,1) ()
↓ ↓
(3,1) (2,4)
↓ ↓
() (3,1,2,4)

## 代码

#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 2e5+7;
int n,a[maxn],log[maxn],f[2][18][maxn],pos[maxn];

int rmq(int k,int l,int r){

int j = log[r-l+1];
return min(f[k][j][l],f[k][j][r-(1<<j)+1]);
}
pair<int,int> cal(int l,int r){
int x = rmq(l&1,l,r);
int y = rmq((pos[x]+1)&1,pos[x]+1,r);

return {-x,-y};
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
pos[a[i]]=i;
}
for(int i=2;i<=n;i++){
log[i]=log[i>>1]+1;
}
for(int l=0;l<2;l++){
for(int i=0;i<n;i++){
f[l][0][i]=(i%2==l)?a[i]:1<<30;
}
for(int k=1;1<<k<=n;k++){
for(int j=0;j+(1<<k)-1<n;j++){
f[l][k][j]=min(f[l][k-1][j],f[l][k-1][j+(1 << k - 1)]);
}
}
}
priority_queue< pair<pair<int,int> ,pair<int,int> > > Q;
Q.push({cal(0,n-1),{0,n-1}});
while(!Q.empty()){
auto it = Q.top();Q.pop();
int x = -it.first.first;
int y = -it.first.second;
printf("%d %d ",x,y);
int l = it.second.first;
int r = it.second.second;
x = pos[x],y = pos[y];
if(l<x-1){
Q.push({cal(l,x-1),{l,x-1}});
}
if(x+1<y-1){
Q.push({cal(x+1,y-1),{x+1,y-1}});
}
if(y+1<r){
Q.push({cal(y+1,r),{y+1,r}});
}
}

}

## F - Prime Flip

Time limit : 2sec / Memory limit : 256MB

## Problem Statement

There are infinitely many cards, numbered 1, 2, 3, … Initially, Cards x1, x2, …, xN are face up, and the others are face down.

Snuke can perform the following operation repeatedly:

Select a prime p greater than or equal to 3. Then, select p consecutive cards and flip all of them.
Snuke's objective is to have all the cards face down. Find the minimum number of operations required to achieve the objective.

Constraints
1≤N≤100
1≤x1<x2<…<xN≤107

## Input

Input is given from Standard Input in the following format:

N
x1 x2 … xN

## Output

Print the minimum number of operations required to achieve the objective.

2
4 5

## Sample Output 1

2
Below is one way to achieve the objective in two operations:

Select p=5 and flip Cards 1, 2, 3, 4 and 5.
Select p=3 and flip Cards 1, 2 and 3

## 代码

#include<iostream>
#include<algorithm>
#include<vector>
#include<string.h>
using namespace std;

const int maxn = 2e5+7;
const int maxm = 1e7+7;
int n,a[maxm];
vector<int>v[2],E[maxn];
bool bio[maxn];
int conn[maxn];
void init(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
scanf("%d",&x);
a[x]=1;
}
}
bool prime(int x){
if(x==1)return false;
for(int i=2;i*i<=x;i++)
if(x%i==0)return false;
return true;
}
bool dfs(int x){
if(bio[x])return false;
bio[x]=true;
for(auto it : E[x]){
if(conn[it] == -1 || dfs(conn[it])){
conn[it] = x;
return true;
}
}
return false;
}
int main(){
init();
memset(conn,-1,sizeof(conn));
for(int i=maxm-1;i;i--){
a[i]^=a[i-1];
if(a[i])v[i%2].push_back(i);
}
for(int i=0;i<v[0].size();i++){
for(int j=0;j<v[1].size();j++){
if(prime(abs(v[0][i]-v[1][j]))){
E[i].push_back(j);
}
}
}

int match = 0;
for(int i=0;i<v[0].size();i++){
memset(bio,false,sizeof(bio));
match+=dfs(i);
}
cout<<v[0].size()+v[1].size()-match+(v[0].size()-match)%2;
return 0;
}
posted @ 2017-08-07 11:19 qscqesze 阅读(...) 评论(...) 编辑 收藏