Codeforces Round #367 (Div. 2)

Posted mountaink

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #367 (Div. 2)相关的知识,希望对你有一定的参考价值。

题目传送门

和队友一起打的两场cf之一,有些代码风格不(比)一(较)样(丑)

A. Beru-taxi

水题

 

技术图片
#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=100010;
int main(){
    int n,zz;
    double a,b,z1,z2,z3,ans;
    while(~scanf("%lf %lf",&a,&b))
    {
        scanf("%d",&n);
        zz = 1;
        for(int i = 0;i < n;i++)
        {
            scanf("%lf %lf %lf",&z1,&z2,&z3);
            if(zz)
            {
                zz = 0;
                ans = sqrt((z1 - a) * (z1 - a) + (z2 - b) * (z2 - b)) / z3;
            }
            else
            {
                ans = min(ans,sqrt((z1 - a) * (z1 - a) + (z2 - b) * (z2 - b)) / z3);
            }
        }
        printf("%.15f
",ans);
    }
}
View Code

 

B. Interesting drink

给出一堆数,q次询问,每次问比这个小的数有几个,sort加lower_bound()

 

技术图片
#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=100010;
vector<int >v;
int n,q;
int main(){
    while(cin>>n)
    {
        v.clear();
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            v.push_back(x);
        }
        sort(v.begin(),v.end());
        cin>>q;
        while(q--)
        {
            int x;
            scanf("%d",&x);
            printf("%d
",upper_bound(v.begin(),v.end(),x)-v.begin());
        }
    }
}
View Code

 

C. Hard problem

给出n个字符串,每个字符串反转需要$ci$的代价,问使得字符串在操作后按字典序非下降排的代价是多少。

$dp[i][0/1]$表示第$i$个串是否反转,然后在合法情况下的最小花费。

技术图片
#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=100010;
long long c[100010],dp[100010][3];
struct s
{
    string s1,s2;
}z[100010];
int main(){
    int n,i,j,si;
    int flag;
    while(~scanf("%d",&n))
    {
        for(i = 0;i < n;i++)
        {
            scanf("%lld",c + i);
        }
        for(i = 0;i < n;i++)
        {
            cin >> z[i].s1;
            si = z[i].s1.size();
            for(j = si - 1;j >= 0;j--)
            {
                z[i].s2.push_back(z[i].s1[j]);
            }
        }
        //memset(dp,0,sizeof(dp));
        dp[0][0] = 0;
        dp[0][1] = c[0];
        flag = 1;
        for(i = 1;i < n;i++)
        {
            dp[i][0] = 1e18;
            dp[i][1] = 1e18;
            if(z[i].s1 >= z[i - 1].s1 && dp[i - 1][0] != 1e18)
            {
                dp[i][0] = min(dp[i][0],dp[i - 1][0]);
            }
            if(z[i].s1 >= z[i - 1].s2 && dp[i - 1][1] != 1e18)
            {
                dp[i][0] = min(dp[i][0],dp[i - 1][1]);
            }
            if(z[i].s2 >= z[i - 1].s1 && dp[i - 1][0] != 1e18)
            {
                dp[i][1] = min(dp[i][1],dp[i - 1][0] + c[i]);
            }
            if(z[i].s2 >= z[i - 1].s2 && dp[i - 1][1] != 1e18)
            {
                dp[i][1] = min(dp[i][1],dp[i - 1][1] + c[i]);
            }
            if(dp[i][0] == 1e18 && dp[i][1] == 1e18)
            {
                flag = 0;
                break;
            }
        }
        if(flag)
        {
            printf("%lld
",min(dp[n - 1][0],dp[n - 1][1]));
        }
        else
        {
            printf("-1
");
        }
    }
}
View Code

 

D. Vasiliy‘s Multiset

01字典树并且带删除操作,每次询问的时候从高位到低位询问,尽量往相反的地方走即可。

技术图片
#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=200010;
int q,x;
char op[3];
int tr[maxn*31][2],tot=1;
int vis[maxn*62];
void insert(int x)
{
    int p=1;
    for(int k=30;k>=0;k--)
    {
        int ch=((x>>k)&1);
        if(tr[p][ch]==0)tr[p][ch]=++tot;
        p=tr[p][ch];
        vis[p]++;
    }
}
void dele(int x){
    int p=1;
    for(int k=30;k>=0;k--)
    {
        int ch=((x>>k)&1);
        p=tr[p][ch];
        vis[p]--;
    }
}
int query(int x)
{
    int res=0,p=1;
    for(int k=30;k>=0;k--)
    {
        int ch=((x>>k)&1);
        if(tr[p][!ch]&&vis[tr[p][!ch]]){
            res|=(1<<k);
            p=tr[p][!ch];
        }else{
            p=tr[p][ch];
        }
    }
    return res;
}
int main(){
    
    while(cin>>q)
    {
        
        insert(0);
        while(q--)
        {
            scanf("%s %d",op,&x);
            if(op[0]==+){
                insert(x);
            }else if(op[0]==-){
                dele(x);
            }else{
                printf("%d
",query(x));
            }
        }
    }
}
View Code

 

E.Working routine

模拟一个二维的链表,每次交换就是改变一下链表的指针即可。

技术图片
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<math.h>
#include<cmath>
#include<time.h>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<algorithm>
#include<numeric>
#include<stack>
#include<bitset>
#include<unordered_map>
const int maxn = 0x3f3f3f3f;
const double EI = 2.71828182845904523536028747135266249775724709369995957496696762772407663035354594571382178525166427;
const double PI = 3.141592653589793238462643383279;
//#ifdef TRUETRUE
//#define gets gets_s
//#endif
using namespace std;
const int Maxn = 1010;
struct node
{
    int l, r, u, d, id, val;
}a[Maxn * Maxn];
int n, m, q, cnt;
int val[Maxn][Maxn];
int c[10][1010], d[10][1010],cc[10][1010],dd[10][1010];
int main(void)
{
    //ios::sync_with_stdio(false);
    int i, j, A, B, C, D, H, W, pos1, pos2;
    while (cin >> n >> m >> q)
    {
        for (i = 0; i <= n + 1; i++)
        {
            for (j = 0; j <= m + 1; j++)
            {
                if (i == 0 || j == 0 || i == n + 1 || j == m + 1)
                {
                    a[i * (m + 2) + j].val = 0;
                }
                else
                {
                    scanf("%d", &a[i * (m + 2) + j].val);
                }
                a[i * (m + 2) + j].id = i * (m + 2) + j;
            }
        }
        for (i = 0; i <= n + 1; i++)
        {
            for (j = 0; j <= m + 1; j++)
            {
                if (i > 0)
                {
                    a[i * (m + 2) + j].u = a[(i - 1) * (m + 2) + j].id;
                }
                if (i < n + 1)
                {
                    a[i * (m + 2) + j].d = a[(i + 1) * (m + 2) + j].id;
                }
                if (j > 0)
                {
                    a[i * (m + 2) + j].l = a[i * (m + 2) + j - 1].id;
                }
                if (j < m + 1)
                {
                    a[i * (m + 2) + j].r = a[i * (m + 2) + j + 1].id;
                }
            }
        }



        while (q--)
        {
            int qq[10], qqq[10];
            scanf("%d %d %d %d %d %d", &A, &B, &C, &D, &H, &W);
            pos1 = 0;
            for (i = 0; i < A; i++)
            {
                pos1 = a[a[pos1].d].id;
            }
            for (i = 0; i < B; i++)
            {
                pos1 = a[pos1].r;
            }
            pos2 = 0;
            for (i = 0; i < C; i++)
            {
                pos2 = a[pos2].d;
            }
            for (i = 0; i < D; i++)
            {
                pos2 = a[pos2].r;
            }

            qq[0] = pos1;
            int tmp1 = pos1;
            for (i = 0; i < W; i++)
            {
                c[0][i] = a[tmp1].u;
                cc[0][i] = tmp1;
                tmp1 = a[tmp1].r;
            }
            tmp1 = a[tmp1].l;
            qq[1] = tmp1;
            for (i = 0; i < H; i++)
            {
                c[1][i] = a[tmp1].r;
                cc[1][i] = tmp1;
                tmp1 = a[tmp1].d;
            }
            tmp1 = a[tmp1].u;
            qq[2] = tmp1;

            for (i = 0; i < W; i++)
            {
                c[2][i] = a[tmp1].d;
                cc[2][i] = tmp1;
                tmp1 = a[tmp1].l;
            }
            tmp1 = a[tmp1].r;
            qq[3] = tmp1;
            for (i = 0; i < H; i++)
            {
                c[3][i] = a[tmp1].l;
                cc[3][i] = tmp1;
                tmp1 = a[tmp1].u;
            }
            tmp1 = a[tmp1].d;




            qqq[0] = pos2;
            int tmp2 = pos2;
            for (i = 0; i < W; i++)
            {
                d[0][i] = a[tmp2].u;
                dd[0][i] = tmp2;
                tmp2 = a[tmp2].r;
            }
            tmp2 = a[tmp2].l;
            qqq[1] = tmp2;
            for (i = 0; i < H; i++)
            {
                d[1][i] = a[tmp2].r;
                dd[1][i] = tmp2;
                tmp2 = a[tmp2].d;
            }
            tmp2 = a[tmp2].u;
            qqq[2] = tmp2;
            for (i = 0; i < W; i++)
            {
                d[2][i] = a[tmp2].d;
                dd[2][i] = tmp2;
                tmp2 = a[tmp2].l;
            }
            tmp2 = a[tmp2].r;
            qqq[3] = tmp1;
            for (i = 0; i < H; i++)
            {
                d[3][i] = a[tmp2].l;
                dd[3][i] = tmp2;
                tmp2 = a[tmp2].u;
            }
            tmp2 = a[tmp2].d;


            
            int qq1[10], qq2[10];
            memcpy(qq1, qq, sizeof(qq));
            memcpy(qq2, qqq, sizeof(qqq));
            for (i = 0; i < W; i++)
            {
                a[cc[0][i]].u = d[0][i];
                a[d[0][i]].d = cc[0][i];
            }
            for (i = 0; i < W; i++)
            {
                a[dd[0][i]].u = c[0][i];
                a[c[0][i]].d = dd[0][i];
            }

            
            


            for (i = 0; i < H; i++)
            {
                a[cc[1][i]].r = d[1][i];
                a[d[1][i]].l = cc[1][i];
            }
            for (i = 0; i < H; i++)
            {
                a[dd[1][i]].r = c[1][i];
                a[c[1][i]].l = dd[1][i];
            }




            for (i = 0; i < W; i++)
            {
                a[cc[2][i]].d = d[2][i];
                a[d[2][i]].u = cc[2][i];
            }
            for (i = 0; i < W; i++)
            {
                a[dd[2][i]].d = c[2][i];
                a[c[2][i]].u = dd[2][i];
            }



            for (i = 0; i < H; i++)
            {
                a[cc[3][i]].l = d[3][i];
                a[d[3][i]].r = cc[3][i];
            }
            for (i = 0; i < H; i++)
            {
                a[dd[3][i]].l = c[3][i];
                a[c[3][i]].r = dd[3][i];
            }
        }
        for (i = 1; i <= n; i++)
        {
            int aa = a[i * (m + 2)].id;
            for (j = 1; j <= m; j++)
            {
                aa = a[aa].r;
                printf("%d", a[aa].val);
                if (j != m)
                {
                    printf(" ");
                }
            }
            printf("
");
        }
    }
    return 0;
}
View Code

 

以上是关于Codeforces Round #367 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章

十字链表 Codeforces Round #367 E Working routine

trie树 Codeforces Round #367 D Vasiliy's Multiset

「专题训练」Hard problem(Codeforces Round #367 Div. 2 C)

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

CodeForces - 367E:Sereja and Intervals(组合数&&DP)