2019 CCPC-Wannafly Winter Camp Div2.day2(补题记录)

一篇来自ACM入门者的补题记录

day2真是让人自闭的一天…

A.Erase Numbers II
题意:给定一个长度为n的正整数序列,它们将按照输入顺序来连接,任务是删除其中(n-2)个数字,使得剩下的数字连接起来最大。

思路:删除(n-2)个数字,其实就是留下两个最大的数字,我们先找到一个最大的数字这是一定要留下来的,由于是按照有序连接,我们就在最大的数字前找一个次大的数字,在最大的数字后面找一个次大的数字,连接得到两个数字,两者比较得到答案。南点是在于大数字的比较方法吧,现场时我沉迷于字符串的比较没有A出来,场外看到题解是开usinged long long存连接的两个整数就能过,总之还是一个简单的模拟题吧(捂脸…)。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 6005;
int A[maxn];
unsigned long long sum(unsigned long long a,int b){
    int d = b;
    while(d > 0){
        d/=10;
        a*=10;
    }
    return a+b;
}
int main()
{
    int T,tcase = 1;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        for(int i = 0;i<n;i++)
            scanf("%d",&A[i]);
        int mmax = 0;
        for(int i = 0;i<n;i++)
            if(A[i]>A[mmax])
                mmax = i;
        unsigned long long ans = 0;
        for(int i = 0;i<mmax;i++)
            ans = max(ans,sum(A[i],A[mmax]));
        for(int i = mmax+1;i<n;i++)
            ans = max(ans,sum(A[mmax],A[i]));
        printf("Case #%d: %llu\n",tcase++,ans);
    }
    return 0;
}

B.Erase Numbers I
题意:与A题一样,只不过删除的数字变为2个。

思路:其实还是一个模拟题。我们需要寻找两个数字去删除,这两个数字必定是序列中长度最短的两个数字,其次,令它和身后的数字比较字典序的大小,如果这个最短数字的字典序小,说明它就是需要删除的数字,否则就是不可删除的数字(这一步直接用字符串默认的比较就可以)。如果所有最短数字都是不可删除的数字,就删除排在最后面的一个最短数字。

由于删除第一个数字以后,序列中的最短长度有可能发生变化,我们一定要更新一下再以同样的方法删除第二个数字,这样操作也就不用考虑每次找到的最短数字的数量有多少个了。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int T;
    scanf("%d",&T);
    for(int tot = 1;tot<=T;tot++){
        int n;
        scanf("%d",&n);
        string G[n+1];
        for(int i = 0;i<n;i++)
            cin>>G[i];
        printf("Case #%d: ",tot);
        int mmin = 0x3f3f3f3f;
        for(int i = 0;i<n;i++){
            int a = G[i].length();
            mmin = min(a,mmin);
        }
        int pos1,pos2;
        for(int i = 0;i<n;i++){
            if(G[i].length() == mmin){
                pos1 = i;
                break;
            }
        }
        while(1){
            if(pos1 == n-1 || G[pos1] < G[pos1+1])
                break;
            else{
                int i;
                for(i = pos1+1;i<n;i++){
                    if(G[i].length() == mmin){
                        pos1 = i;
                        break;
                    }
                }
                if(i == n)
                    break;
            }
        }
        mmin = 0x3f3f3f3f;
        for(int i = 0;i<n;i++){
            if(i == pos1)
                continue;
            int a = G[i].length();
            mmin = min(a,mmin);
        }
        for(int i = 0;i<n;i++){
            if(i == pos1)
                continue;
            if(G[i].length() == mmin){
                pos2 = i;
                break;
            }
        }
        while(1){
            if((pos2+1 == pos1 && (pos1 == n-1 || G[pos2] < G[pos2+2])) || pos2+1 != pos1 &&(pos2 == n-1 || G[pos2] < G[pos2+1]))
                break;
            else{
                int i;
                for(i = pos2+1;i<n;i++){
                    if(i == pos1)
                        continue;
                    if(G[i].length() == mmin){
                        pos2 = i;
                        break;
                    }
                }
                if(i == n)
                    break;
            }
        }
        for(int i = 0;i<n;i++)
            if(i != pos1 && i != pos2)
                cout<<G[i];
        printf("\n");
    }
    return 0;
}

H.Cosmic Cleaner
题意:三维空间中有一个中心位于(x’,y’,z’)半径为r’的大球,同时存在n个小球,问所有小球与大球相交的体积之和为多少?

思路:球缺模板题,我手上空有两球相交求交点的板子,不会推球缺(捂脸…),队友现场推出来了。代码就不贴了,学习学习球缺的推导:https://blog.csdn.net/Enterprise_/article/details/81624174

K.Sticks
题意:给定12根木棒的长度,问这些木棒最多能拼成多少个三角形,输出最大数量和具体方案。

思路:枚举所有情况,总情况应该是C(3,12)*C(3,9)*C(3,6),去重:C(3,12)*C(3,9)*C(3,6)/A(4,4),然后遍历判断,预处理总情况,时间复杂度应该够的。

但我不会啊(捂脸…),这题卡了挺久,不知道怎么去重,网上的题解还没看懂,自己的枚举总是TLE,哎…

暂未解决。

猜你喜欢

转载自blog.csdn.net/weixin_44583165/article/details/87864174
今日推荐