7.23杭電多校~~~自閉進行時ing

A題

給出n,求xyz的最大值,要求n = x + y + z 且 n 能整除x y z,沒有輸出-1

解:1 = 1/3 + 1/3 + 1/3 = 1/2 + 1/4 + 1/4,只要能被3/4整除就有解

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
ll T,n;

int main()
{
    scanf("%lld",&T);
    while(T--)
    {
        scanf("%lld",&n);
        if(n % 3 == 0) printf("%lld\n",(n / 3) * (n / 3) * (n / 3));
        else if(n % 4 == 0) printf("%lld\n",(n / 2) * (n / 4) * (n / 4));
        else printf("-1\n");
    }
    return 0;
}

 

B題 給你n個括號字符串,排序這些括號字符串,怎麼排序能使其配對最多並輸出總共有幾個括號可以參與配對

解:預處理每個字符串,計算出每個字符串本身可以配對幾個,有幾個'('和')'還沒進行配對(棧)

        排序(誰能對形成配對的貢獻大,字符串裏 '(' 出現次數比 ')'多,它比較適合排前面,能夠使自己對整個配對做出的貢獻最大,a和b比較的話,如果a和b都是'('貢獻大的話,誰的')'小就排前面,因爲相對來說')'的要往後排,相對貢獻會大一些)

 

D題

構造一個序列,使得m個給定區間內的數字各不相同並且序列的字典序最小

解:區間位置有相離,相交,重合3種

      先將區間按左端點排個序

      重合不需要考慮,因爲滿足大區間的也滿足小區間

      相交:前一個區間先選,後一個區間的數字從不重合部分開始,依次選重合區間沒有選過的數字

#include<bits/stdc++.h>
using namespace std;

struct node
{
    int l,r;
}a[100010];

int T,n,m,k,l,r;
int ans[100010],num[100010];

bool cmp(node k,node p)
{
    if(k.l == p.l) return k.r > p.r;
    return k.l < p.l;
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        memset(ans,0,sizeof(ans));
        memset(num,0,sizeof(num));
        for(int i = 0;i < m; ++i) scanf("%d%d",&a[i].l,&a[i].r);
        sort(a,a + m,cmp);
        for(int j = a[0].l;j <= a[0].r; j++)   
            ans[j] = j - a[0].l + 1;
        l = a[0].l;
        r = a[0].r;
        for(int i = 1;i < m; ++i)
        {
            if(r >= a[i].r) continue;
            k = 1;
            if(a[i].l <= r)   //相交區間
            {
                for(int j = a[i].l;j <= r; ++j)
                    num[ans[j]] = i;
                for(int j = r + 1;j <= a[i].r; ++j)
                {
                    while(num[k] == i) ++k;
                    ans[j] = k++;
                }
            }
            else   //不相交區間
                for(int j = a[i].l;j <= a[i].r; ++j)
                    ans[j] = k++;
            l = a[i].l;
            r = a[i].r;
        }
        for(int i = 1;i <= n; ++i)
        {
            if(i > 1) printf(" ");
            if(ans[i]) printf("%d",ans[i]);
            else printf("1");
        }
        printf("\n");
    }
    return 0;
}

ps:正解:利用set的去重和排序功能,利用tot標記一下當前可入set的左界(可重複利用),pre數組記錄的是區間左界

#include<bits/stdc++.h>
using namespace std;

int T,n,m,l,r,tot;
set<int>s;
int ans[100100],pre[100100];

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n; ++i) pre[i] = i,s.insert(i);
        for(int i = 0;i < m; ++i)
        {
            scanf("%d%d",&l,&r);
            pre[r] = min(pre[r],l);
        }
        for(int i = n - 1;i >= 1; --i)
            pre[i] = min(pre[i],pre[i + 1]);
        tot = 1;
        for(int i = 1;i <= n; ++i)
        {
            while(tot < pre[i]) s.insert(ans[tot++]);
            ans[i] = *s.begin();
            s.erase(ans[i]);
        }
        for(int i = 1;i < n; ++i)
            printf("%d ",ans[i]);
        printf("%d\n",ans[n]);
    }
    return 0;
}

K題   

給出西八區的時間,求其他時區的時間

解:極度玄學...咱也不知道爲啥錯...咱也不知道改了哪裏就對了

教訓:避免浮點數的加減,全部換算成分鐘

#include<bits/stdc++.h>
using namespace std;

int T,n,m,len;
string s;
double t,f;

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d UTC%lf",&n,&m,&t);
        int k = n * 60 + m - 8 * 60;
        int p = t * 10;
        k += p * 6;
        while(k < 0) k += 24 * 60;
        k %= (24 * 60);
        m = k % 60;
        n = k / 60;
        printf("%02d:%02d\n",n,m);
    }
    return 0;
}

 

 

發佈了107 篇原創文章 · 獲贊 7 · 訪問量 5179
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章