您的位置:首页 > 其它

Codeforces IndiaHacks 2016 - Online Edition (Div. 1 + Div. 2)

2016-03-21 21:43 423 查看

C. Bear and Up-Down

当不满足要求的数超过4个的时候,肯定是无解的,否则用每个数和这4个数交换,然后check。。比赛的时候写了很繁琐的分类讨论,竟然没挂。。

#include <bits/stdc++.h>
#include <unordered_map>

#define ll long long

using namespace std;

int a[150010];

int err[150010];
int n;

bool judge(){
for(int i=1;i<n;i++){
if(i&1){
if(a[i]>=a[i+1]){
return 0;
}
}else{
if(a[i]<=a[i+1]){
return 0;
}
}
}
return 1;
}

int main(){

cin>>n;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}

int cnt= 0;

for(int i=1;i<n;i++){
if(i&1){
if(a[i]>=a[i+1]){
err[cnt++] = i;
}
}else{
if(a[i]<=a[i+1]){
err[cnt++] = i;
}
}
}
int ans = 0;

if(cnt>4){

}else if(cnt==4){
if(err[0]+1==err[1] && err[2]+1==err[3]){
swap(a[err[1]],a[err[3]]);
ans+=judge();
swap(a[err[1]],a[err[3]]);

}else{

}
}else if(cnt==3){
if(err[0]+2==err[2]){
swap(a[err[1]],a[err[2]]);
ans+=judge();
swap(a[err[1]],a[err[2]]);

swap(a[err[1]],a[err[2]+1]);
ans+=judge();
swap(a[err[1]],a[err[2]+1]);

swap(a[err[0]],a[err[2]]);
ans+=judge();
swap(a[err[0]],a[err[2]]);
}if(err[0]+1==err[1]){
swap(a[err[1]],a[err[2]]);
ans+=judge();
swap(a[err[1]],a[err[2]]);

swap(a[err[1]],a[err[2]+1]);
ans+=judge();
swap(a[err[1]],a[err[2]+1]);

}else if(err[1]+1==err[2]){
swap(a[err[0]],a[err[2]]);
ans+=judge();
swap(a[err[0]],a[err[2]]);

swap(a[err[0]+1],a[err[2]]);
ans+=judge();
swap(a[err[0]+1],a[err[2]]);

}else{

}
}else if(cnt==2){
if(err[0]+1==err[1]){
swap(a[err[0]],a[err[1]+1]);
ans+=judge();
swap(a[err[0]],a[err[1]+1]);

for(int i=1;i<=n;i++){
swap(a[i],a[err[1]]);

bool ok = 1;
for(int j=i-3;j<=i+3;j++){
if(j<1)continue;
if(j>=n)continue;
if(j&1){
if(a[j]>=a[j+1]){
ok = 0;
}
}else{
if(a[j]<=a[j+1]){
ok = 0;
}
}
}

for(int j=err[1]-3;j<=err[1]+3;j++){
if(j<1)continue;
if(j>=n)continue;
if(j&1){
if(a[j]>=a[j+1]){
ok = 0;
}
}else{
if(a[j]<=a[j+1]){
ok = 0;
}
}
}

swap(a[i],a[err[1]]);
ans+=ok;
}

}else{
swap(a[err[0]],a[err[1]]);
ans+=judge();
swap(a[err[0]],a[err[1]]);

swap(a[err[0]],a[err[1]+1]);
ans+=judge();
swap(a[err[0]],a[err[1]+1]);

swap(a[err[0]+1],a[err[1]]);
ans+=judge();
swap(a[err[0]+1],a[err[1]]);

swap(a[err[0]+1],a[err[1]+1]);
ans+=judge();
swap(a[err[0]+1],a[err[1]+1]);
}
}else if(cnt==1){
for(int i=1;i<=n;i++){
swap(a[i],a[err[0]]);

bool ok = 1;
for(int j=i-3;j<=i+3;j++){
if(j<1)continue;
if(j>=n)continue;
if(j&1){
if(a[j]>=a[j+1]){
ok = 0;
}
}else{
if(a[j]<=a[j+1]){
ok = 0;
}
}
}

for(int j=err[0]-3;j<=err[0]+3;j++){
if(j<1)continue;
if(j>=n)continue;
if(j&1){
if(a[j]>=a[j+1]){
ok = 0;
}
}else{
if(a[j]<=a[j+1]){
ok = 0;
}
}
}

swap(a[i],a[err[0]]);
ans+=ok;
}

for(int i=1;i<=n;i++){
if(i==err[0])continue;
swap(a[i],a[err[0]+1]);

bool ok = 1;
for(int j=i-3;j<=i+3;j++){
if(j<1)continue;
if(j>=n)continue;
if(j&1){
if(a[j]>=a[j+1]){
ok = 0;
}
}else{
if(a[j]<=a[j+1]){
ok = 0;
}
}
}

for(int j=err[0]-3;j<=err[0]+3;j++){
if(j<1)continue;
if(j>=n)continue;
if(j&1){
if(a[j]>=a[j+1]){
ok = 0;
}
}else{
if(a[j]<=a[j+1]){
ok = 0;
}
}
}

swap(a[i],a[err[0]+1]);
ans+=ok;
}
}

cout<<ans<<endl;
return 0;
}


D. Delivery Bears

这是一道好题!解法是二分答案,然后跑最大流判是否可行。判断方法是将边的流量改为它除以答案的值,向下取整,如果最大流不小于x就是合法。

另外要注意,二分写成循环固定次数会比较好。

#include <bits/stdc++.h>
#include <unordered_map>

#define ll long long
using namespace std;

int n,m;
double x;

const int inf=0xfffff;
const int N = 55;
int  pre
;

double maxflow,dp

;

double tmp

;

void Edmonds_Karp(int start, int end, int m){
while(1){
queue<int> p;
double minflow = inf;
p.push(1);
memset(pre, 0, sizeof(pre));
while(!p.empty()){
int u = p.front();
p.pop();
if(u == end)
break;
for(int i = 1;i <= m;i++)
if(dp[u][i] > 0&&pre[i] == 0){
pre[i] = u;
p.push(i);
}
}
if(pre[end] == 0)
break;
for(int i = end;i != start;i = pre[i])
minflow = min(minflow, dp[pre[i]][i]);
for(int i = end;i != start;i = pre[i])  {
dp[pre[i]][i] -= minflow;
dp[i][pre[i]] += minflow;
}
maxflow+=minflow;
}
}

int main(){
cin>>n>>m>>x;
for(int i=1;i<=m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
dp[a][b]+=c;
}
memcpy(tmp,dp,sizeof(dp));

double l=0;
double r=1000000;
double mid = 0;
//注意这个二分的姿势
for(int tt=0;tt<66;tt++){
mid = (l+r)/2;
memcpy(dp,tmp,sizeof(dp));
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
dp[i][j] = floor(dp[i][j]/mid);
}
}
maxflow = 0;
Edmonds_Karp(1,n,n);

if(maxflow>=x){
l=mid;
}else{
r=mid;
}
}

printf("%.10f\n",mid*x);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces