2019牛客多校第十场

B.Coffee Chicken

对于 S ( n ) S(n) S(n),考虑某个字母是从 S ( n − 1 ) S(n-1) S(n1)转移还是从 S ( n − 2 ) S(n-2) S(n2)转移

#include<bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define N 10005
using namespace std;
int T,n,q,p,t;
long long k,kk;
long long f[N];
string ch[3];
int main()
{
    scanf("%d",&T);
    f[1] = 6; f[2] = 7; t = 2;
    while (f[t] < 1e12) {t++; f[t] = f[t-1] + f[t-2];}  
    ch[1] = "COFFEE"; ch[2] = "CHICKEN";
    while (T--)
    {
        scanf("%d%lld",&n,&k); kk = k;
        q = 10;
        while (q--)
        {
            p = min(n,t);
            if (k > f[p]) break;
            while (p > 2)
            {
                if (k <= f[p-2]) p = p - 2; else
                {
                    k = k - f[p-2];
                    p = p - 1;
                }
            }
            //cout<<p<<" "<<k<<endl;
            printf("%c",ch[p][k-1]);
            kk++; k = kk;
        }
        printf("\n");
    }
    return 0;
}

E.Hilbert Sort

第一次抢下一血好激动啊
大概就是每次四分,递归到某一块
然后根据当前的起点和终点(op=1/2/3/4)直接暴力手算找出四块的op
其实应该就是一个分形

#include<bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define N 1000005
using namespace std;
struct www{int x,y; long long v;} f[N];
int n,k,len,i;
bool cmp(const www &a,const www &b) {return a.v < b.v;}
long long dfs(int op,int x,int y,int len)
{
    if (len == 1) return 1;
    int len2 = len / 2;
    int op2;
    long long d = 1ll * (len / 2) * (len / 2);
    if (x <= len2 && y <= len2) op2 = 1;
    if (x <= len2 && y > len2) op2 = 2;
    if (x > len2 && y <= len2) op2 = 3;
    if (x > len2 && y > len2) op2 = 4;
    if (x > len2) x -= len2;
    if (y > len2) y -= len2;
    if (op == 1)
    {
        if (op2 == 1) return dfs(2,x,y,len2);
        if (op2 == 3) return dfs(1,x,y,len2) + d;
        if (op2 == 4) return dfs(1,x,y,len2) + d * 2;
        if (op2 == 2) return dfs(3,x,y,len2) + d * 3;
    }
    if (op == 2)
    {
        if (op2 == 1) return dfs(1,x,y,len2);
        if (op2 == 2) return dfs(2,x,y,len2) + d;
        if (op2 == 4) return dfs(2,x,y,len2) + d * 2;
        if (op2 == 3) return dfs(4,x,y,len2) + d * 3;
    }
    if (op == 3)
    {
        if (op2 == 4) return dfs(4,x,y,len2);
        if (op2 == 3) return dfs(3,x,y,len2) + d;
        if (op2 == 1) return dfs(3,x,y,len2) + d * 2;
        if (op2 == 2) return dfs(1,x,y,len2) + d * 3;
    }
    if (op == 4)
    {
        if (op2 == 4) return dfs(3,x,y,len2);
        if (op2 == 2) return dfs(4,x,y,len2) + d;
        if (op2 == 1) return dfs(4,x,y,len2) + d * 2;
        if (op2 == 3) return dfs(2,x,y,len2) + d * 3;
    }
}
int main()
{
    scanf("%d%d",&n,&k);
    len = 1 << k;
    fo(i,1,n)
    {
        scanf("%d%d",&f[i].x,&f[i].y);
        f[i].v = dfs(1,f[i].x,f[i].y,len);
    }
    sort(f+1,f+n+1,cmp);
    fo(i,1,n) printf("%d %d\n",f[i].x,f[i].y);
    return 0;
}

F.Popping Balloons

没想到暴力可以艹过去
考虑暴力: O ( n 2 ) O(n^2) O(n2)枚举水平和竖直的中间一枪,去掉重复情况
优化:水平方向从大到小枚举,竖直方向也从大到小枚举
剪枝:如果当前不去重的答案已经小于目前的ans就直接break

#include<bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define N 100005
using namespace std;
struct node
{
    int x,y;
    bool operator < (const node &rhs) const
    {
        return x<rhs.x || (x==rhs.x && y<rhs.y);
    }
};
struct val{int v,p;} numx[N],numy[N];
map<node,int> mp;
int n,r,i,j,x,y,res,linex,liney,v1,v2;
int num1[N],num2[N];
bool cmp(const val &a,const val &b) {return a.v > b.v;}
int check(int x,int y)
{
    int ans = 0;
    int i,j,xx,yy;
    fo(i,-1,1)
    fo(j,-1,1)
    {
        xx = x + r * i;
        yy = y + r * j;
        node p = node{xx,yy};
        ans += mp[p];
    }
    return ans;
}
int main()
{
    scanf("%d%d",&n,&r);
    fo(i,1,n)
    {
        scanf("%d%d",&x,&y);
        num1[x]++;
        num2[y]++;
        node p = node{x,y};
        mp[p]++;
    }
    fo(i,0,1e5)
    {
        numx[i].p = numy[i].p = i;
        numx[i].v = num1[i];
        if (i-r >= 0) numx[i].v += num1[i-r];
        if (i+r <= 1e5) numx[i].v += num1[i+r];
        numy[i].v = num2[i];
        if (i-r >= 0) numy[i].v += num2[i-r];
        if (i+r <= 1e5) numy[i].v += num2[i+r];
    }
    sort(numx,numx+100000+1,cmp);
    sort(numy,numy+100000+1,cmp);
    res = 0;
    fo(i,0,1e5)
    {
        linex = numx[i].p; v1 = numx[i].v;
        fo(j,0,1e5)
        {
            liney = numy[j].p; v2 = numy[j].v;
            if (v1 + v2 < res) break;
            res = max(res,v1+v2-check(linex,liney));
        }
    }
    cout<<res<<endl;
    return 0;
}

H.Stammering Chemists

先判掉有度为4的、两个度为3的、最大度为2的情况
然后判断度为3的那个点连出去的三个点的度是112还是122

#include<bits/stdc++.h>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define N 10
using namespace std;
int T,i,j,x,y;
int f[N][N],num[N],d[N];
int main()
{
    scanf("%d",&T);
    while (T--)
    {
        fo(i,1,6) fo(j,1,6) f[i][j] = 0;
        fo(i,1,5)
        {
            scanf("%d%d",&x,&y);
            f[x][y] = f[y][x] = 1;
        }
        fo(i,1,6)
        {
            d[i] = 0;
            fo(j,1,6) d[i] += f[i][j];
        }
        num[1] = num[2] = num[3] = num[4] = 0;
        fo(i,1,6) num[d[i]]++;
        if (num[4] > 0) {printf("2,2-dimethylbutane\n"); continue;}
        if (num[3]  == 2) {printf("2,3-dimethylbutane\n"); continue;}
        if (num[3]  == 0) {printf("n-hexane\n"); continue;}
        x = 0;
        fo(i,1,6)
        if (d[i] == 3)
        {
            fo(j,1,6)
            if (f[i][j] == 1)
            {
                if (d[j] == 2) x++;
            }
        }
        if (x == 1) {printf("2-methylpentane\n"); continue;}
        if (x == 2) {printf("3-methylpentane\n"); continue;}
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值