Codeforces Round #197 (Div. 2)

-----------------

A. Helpful Maths

----

将一个由+和123组成的式子从小到大排序...

----

#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

const int maxn=1111;
char s[maxn];
vector<int>vc;
int main()
{
    vc.clear();
    cin>>s;
    int len=strlen(s);
    for (int i=0;i<len;i++)
    {
        if (s[i]>='1'&&s[i]<='3')
        {
            vc.push_back(s[i]-'0');
        }
    }
    sort(vc.begin(),vc.end());
    cout<<vc[0];
    for (int i=1;i<(int)vc.size();i++)
    {
        cout<<"+"<<vc[i];
    }
    cout<<endl;
    return 0;
}
-----------------

B. Xenia and Ringroad

----

1..n地点环形排列,只能顺时针前进,给出m个目标地点,问按顺序转一遍需要经过几个地点。

----

#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

const int maxn=1111;
char s[maxn];
vector<int>vc;
int main()
{
    vc.clear();
    cin>>s;
    int len=strlen(s);
    for (int i=0;i<len;i++)
    {
        if (s[i]>='1'&&s[i]<='3')
        {
            vc.push_back(s[i]-'0');
        }
    }
    sort(vc.begin(),vc.end());
    cout<<vc[0];
    for (int i=1;i<(int)vc.size();i++)
    {
        cout<<"+"<<vc[i];
    }
    cout<<endl;
    return 0;
}

-----------------

C. Xenia and Weights

----

有质量在1...10之间的一些砝码,每个质量都有无数个,按照一定规则放在天平上。

左->右->左->右.....

假如第i步放了质量为x的砝码,则第i+1步不能放x。

第i+1步的天平倾斜方向与第i步不同。不能平衡。

----

设天平两端质量差为w。

则0<w<10,第x次放的砝码质量为t且t>w。

第x+1次两端质量差为t-w。

搜索、DP解决。

----

vector<int>ans;
char s[13];
int m;
bool dfs(int x,int w){
    if (x>=m){
        return true;
    }
    for (int i=w+1;i<=10;i++){
        if (s[i]=='1'){
            if (sz(ans)==0||(sz(ans)>0&&ans[x-1]!=i)){
                ans.push_back(i);
                if (dfs(x+1,i-w)) return true;
                ans.pop_back();
            }
        }
    }
    return false;
}

int main()
{
    ans.clear();
    cin>>(s+1)>>m;
    if (dfs(0,0)){
        cout<<"YES"<<endl;
        REP(i,sz(ans)) cout<<ans[i]<<" ";
        cout<<endl;
    }
    else{
        cout<<"NO"<<endl;
    }
    return 0;
}
-----------------

D. Xenia and Bit Operations

----

给出2^n个数,相邻的两两做OR操作,得到的新数列两两做XOR,新数列再做OR...如此重复最终得到一个值V。

给出m个操作。每次将原数列的第p项的值改为b,并输出V。

----

线段树维护单点更新,对每一层交替用OR和XOR维护。输出根节点的值即可。

----

int num[N];
struct Tree{
    int l,r;
    int v;
    int d;
}tree[N*4];

void push_up(int root){
    if (tree[root].d&1) tree[root].v=tree[root<<1].v|tree[root<<1|1].v;
    else                tree[root].v=tree[root<<1].v^tree[root<<1|1].v;
}

void build(int root,int l,int r){
    tree[root].l=l;
    tree[root].r=r;
    if(tree[root].l==tree[root].r){
        tree[root].v=num[l];
        tree[root].d=0;
        return;
    }
    int mid=(l+r)/2;
    build(root<<1,l,mid);
    build(root<<1|1,mid+1,r);
    tree[root].d=tree[root<<1].d+1;
    push_up(root);
}
void update(int root,int pos,int val){
    if(tree[root].l==tree[root].r){
        tree[root].v=val;
        return;
    }
    int mid=(tree[root].l+tree[root].r)/2;
    if(pos<=mid) update(root<<1,pos,val);
    else update(root<<1|1,pos,val);
    push_up(root);
}
int query(){
    return tree[1].v;
}

int main()
{
    int n,m,mn;
    int p,b;
    cin>>n>>m;
    mn=int(pow(2,n));
    for (int i=1;i<=mn;i++) cin>>num[i];
    build(1,1,mn);
    while (m--){
        cin>>p>>b;
        update(1,p,b);
        cout<<query()<<endl;
    }
    return 0;
}

-----------------

E. Three Swaps

----

有1...n匹马,有操作(l,r)可翻转区间[l,r]。

最多操作三次,给出最终结果,要求找到一个可能的操作序列。

----

由于数量极少,可以直接搜索。

----

const int maxn=1111;
int n;
int a[maxn];
vector< pair<int,int> > ans;

int left(){
    for (int i=1;i<=n;i++){
        if (a[i]!=i) return i;
    }
    return 0;
}
int right(){
    for (int i=n;i>=1;i--){
        if (a[i]!=i) return i;
    }
    return 0;
}
int getX(int x){
    for (int i=1;i<=n;i++){
        if (x==a[i]) return i;
    }
    return 0;
}
bool dfs(int x){
    int l,r;
    l=left();
    if (l==0) return true;
    if (x>=3) return false;
    r=getX(l);
    reverse(a+l,a+r+1);
    if (dfs(x+1)){
        ans.push_back(make_pair(l,r));
        return true;
    }
    reverse(a+l,a+r+1);
    r=right();
    l=getX(r);
    reverse(a+l,a+r+1);
    if (dfs(x+1)){
        ans.push_back(make_pair(l,r));
        return true;
    }
    reverse(a+l,a+r+1);
    return false;
}

int main()
{
    ans.clear();
    cin>>n;
    REP_1(i,n) cin>>a[i];
    dfs(0);
    cout<<ans.size()<<endl;
    REP(i,sz(ans)){
        cout<<ans[i].first<<" "<<ans[i].second<<endl;
    }
    return 0;
}


-----------------


原文地址:https://www.cnblogs.com/cyendra/p/3681588.html