Codeforces Round #676 (Div. 2)

A. XORwice

a^b没啥好说.(a^x) + (b^x) >=a^b

B. Putting Bricks in the Wall

考虑到起点终点位置固定,所以只用封死四个位子就行。

起点右,起点下,终点上,终点左。

那么十六种情况,写一下?

C. Palindromifier

对于任意串,比如1234。

L 2,先翻出一个2,得到21234

R 2,再翻出123,得到21234321

R len*2-1  翻出倒数第二个2,得到212343212

D. Hexagons

给定了六个方向的花费,我们发现一个方向可以有其他方向中选两个构成。

所以我们进行一番比较取小,得到六个方向的真正花费。

然后我们把方向拉成我们熟悉的方向

竖轴x,横轴y  (x,y)

红色为终点

我们现在有两种方式到达终点,因为向上这段花费是相同的,所以我们减去,得到下图

我们发现,右上的紫色方向,实际上已经被上和右两个方向优化过了,因此紫色一定是最优解,但是绿色不一定是。

我们选择走紫色。

这个时候我们发现另一个问题

我们发现向上的花费已经被左和右上优化过了。所以就向上好了。

但是当终点在x<0&&y>0的情况下,我们发现没有优化路径了,所以就直接写平移路径就好。(此处懒得画图

其他情况类似推一推,该睡觉了

#include<cstdio>
#include<cmath>
#include<iostream> 
#include<cstring> 
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<iomanip>
#define inf 24300000000000001
#define ll long long
using namespace std;
ll c[10],ans,t,x,y;
int main(){
    ans=0;
    scanf("%lld",&t);
    while(t--){
        scanf("%lld%lld",&x,&y);
        for(int i=1;i<=6;++i)
            scanf("%lld",&c[i]);
        c[1]=min(c[1],c[6]+c[2]);
        c[2]=min(c[2],c[1]+c[3]);
        c[3]=min(c[3],c[2]+c[4]);
        c[4]=min(c[4],c[3]+c[5]);
        c[5]=min(c[5],c[6]+c[4]);
        c[6]=min(c[6],c[5]+c[1]);
        if (x>=0&&y>=0){
            if(x>y)    cout<< y*c[1]+(x-y)*c[6] <<"\n";
            else    cout<< x*c[1]+(y-x)*c[2] <<"\n";
        }
        else if(x<=0&&y<=0){
            if(x>y) cout <<-x*c[4]+(x-y)*c[5] <<"\n";
            else    cout <<-y*c[4]+(y-x)*c[3] <<"\n";
        }
        else if(x>=0&&y<=0){
            cout<< x*c[6]-y*c[5] <<"\n";
        }
        else if(x<=0&&y>=0){
            cout<< -x*c[3]+y*c[2] <<"\n";
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/PdrEam/p/13843683.html