Codeforces补题2020.3.4 (Challenge 2020)

A.Kuroni and the Gifts

Kuroni有n个女儿。作为送给他们的礼物,他买了n条项链和n条手镯:

第i条项链的亮度为ai,其中所有ai成对出现(即,所有ai不同), 第i个手镯的亮度为bi,其中所有bi都是成对的(即所有bi都是不同的)。 Kuroni希望给每个女儿精确地给一条项链和一条手链。为了确保它们看起来都是独一无二的,送给每个女儿的礼物的总亮度应该成对地分开。形式上,如果第i个女儿收到一条亮度为xi的项链和一条亮度为yi的手链,则xi + yi之和应该成对地分开。帮助Kuroni分发礼物。

例如,如果亮度为a = [1,7,5]和b = [6,1,2],则我们可以如下分配礼物:

将第三条项链和第一个手镯送给第一个女儿,总亮度为a3 + b1 = 11。 将第一条项链和第三条手链交给第二个女儿,总亮度为a1 + b3 = 3。 将第二条项链和第二条手链送给第三个女儿,总亮度为a2 + b2 = 8。 这是无效分配的示例:

将第一个项链和第一个手镯送给第一个女儿,总亮度为a1 + b1 = 7。 将第二条项链和第二条手链交给第二个女儿,总亮度为a2 + b2 = 8。 将第三条项链和第三条手链送给第三个女儿,总亮度为a3 + b3 = 7。 这种分配是无效的,因为第一个和第三个女儿收到的礼物的总亮度相同。不要让他们如此沮丧!

输入值 输入包含多个测试用例。第一行包含一个整数t(1≤t≤100)-测试用例的数量。测试用例的描述如下。

每个测试用例的第一行包含一个整数n(1≤n≤100)-女儿,项链和手镯的数量。

每个测试用例的第二行包含n个不同的整数a1,a2,…,an(1≤ai≤1000)—项链的亮度。

每个测试用例的第三行包含n个不同的整数b1,b2,…,bn(1≤bi≤1000)-手镯的亮度。

输出量 对于每个测试用例,打印一行包含n个整数x1,x2,…,xn的行,表示第i个女儿收到一条亮度为xi的项链。在下一行中,打印n个整数y1,y2,…,yn,表示第i个女儿收到亮度为yi的手镯。

x1 + y1,x2 + y2,…,xn + yn之和应全部不同。 x1,…,xn的编号应按顺序等于数字a1,…,an,编号y1,…,yn的编号应按顺序等于数字b1,…,bn。

可以证明答案总是存在的。如果有多个可能的答案,则可以打印其中的任何一个。

题解:

简单排序

#include<bits/stdc++.h>
using namespace std;
const int maxn=1014;
int a[maxn];
int b[maxn];
int N;
int main () {
    int T;
    scanf("%d",&T);
    while (T--) {
        scanf("%d",&N);
        for (int i=1;i<=N;i++)
            scanf("%d",&a[i]);
        for (int i=1;i<=N;i++)
            scanf("%d",&b[i]);
        sort(a+1,a+N+1);
        sort(b+1,b+N+1);
        for (int i=1;i<=N;i++)
            printf("%d ",a[i]);
        printf ("
");
        for (int i=1;i<=N;i++)
            printf("%d ",b[i]);
        printf ("
");
    } 
    return 0;
}
View Code

B.Kuroni and Simple Strings

现在Kuroni已经10岁了,他已经是个大男孩了,不再喜欢现在的整数数组了。今年,他希望将Bracket序列作为生日礼物。更具体地说,他希望括号序列如此复杂,以至于无论他多么努力,他都将无法删除一个简单的子序列!

我们说,如果n个字符的长度n为偶数且为正,其前n2个字符为'(',最后n2个字符为')',则由n个字符'('或')'组成的字符串很简单。例如,字符串()和(())很简单,而字符串)(和()()并不简单。

Kuroni将被赋予一个由字符'('和')'组成的字符串(给定的字符串不一定是简单的)。一个操作包括选择构成简单字符串的字符串字符的子序列,然后从字符串中删除该子序列的所有字符。请注意,此子序列不必是连续的。例如,他可以将操作应用于字符串')()((()))',以选择粗体字符的子序列,因为它形成了简单的字符串'(())',所以从字符串中删除了这些粗体字符并获得'))()'。

Kuroni必须在字符串上执行最少数量的操作,这样就无法对其余字符串执行更多操作。结果字符串不必为空。

由于给定的字符串太大,Kuroni无法找出如何最大程度地减少操作次数。你能帮他做吗?

如果可以通过删除几个(可能为零或全部)字符从b获得a,则字符序列a是字符串b的子序列。

输入值 输入的唯一行包含由字符“(”和“)”组成的字符串s(1≤| s |≤1000),其中| s |是s的长度。

输出量 在第一行中,输出整数k-您必须应用的最小操作数。然后,以以下格式打印2k行以描述操作:

对于每个操作,请打印包含整数m的行,该整数m是要删除的子序列中的字符数。

然后,打印包含m个整数的行,这些整数1≤a1<a2 <⋯<am —您将删除的字符的索引。所有整数必须小于或等于当前字符串的长度,并且相应的子序列必须形成一个简单的字符串。

如果有多个有效的最小k操作序列,则可以打印其中的任何一个。

题解:

#include<bits/stdc++.h>
using namespace std;
int main () {
    string s;
    cin>>s;
    int len=s.length();
    int pref=0;
    int suf=0;
    for (int i=0;i<len;i++)
        suf+=s[i]==')';
    int cut=-1;
    for (int i=0;i<=len;i++) {
        if (pref==suf) {
            cut=i;
            break;
        }
        if (s[i]=='(') {
            pref++;
        }
        else suf--;
    }
    vector<int> ans;
    for (int i=0;i<cut;i++) 
        if (s[i]=='(') ans.push_back(i);
    for (int i=cut;i<len;i++)
        if (s[i]==')') ans.push_back(i);
    if (ans.empty()) printf ("0
");
    else {
        printf ("1
");
        printf ("%d
",ans.size());
        for (int i=0;i<ans.size();i++) {
            if (i) printf (" ");
            printf ("%d",ans[i]+1);
        }
        printf ("
");
    }
    return 0;
} 
View Code

C.Kuroni and Impossible Calculation

为了成为Codeforce的王者,Kuroni必须解决以下问题。

给他n个数字a1,a2,…,an。 帮助Kuroni计算∏1≤i <j≤n| ai-aj |。 结果可能非常大,以模m形式输出。

如果您不熟悉缩写符号,,1≤i<j≤n| ai-aj | 等于| a1-a2 |⋅| a1-a3 |⋅…⋅| a1-an |⋅| a2-a3 |⋅| a2-a4 |⋅…⋅| a2-a |⋅…⋅| an-1- an |。 换句话说,这是| ai-aj |的乘积 对于所有1≤i<j≤n。

输入值 第一行包含两个整数n,m(2≤n≤2⋅105,1≤m≤1000)-数字和模数。

第二行包含n个整数a1,a2,…,an(0≤ai≤109)。

输出量 输出单个数字— ∏1≤i <j≤n| ai-aj | modm。

题解:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2000005;
int f1[maxn];
int x[maxn];
int main () {
    int N,M;
    scanf("%d%d",&N,&M);
    for (int i=0;i<N;i++) {
        scanf("%d",&x[i]);
        f1[x[i]%M]++;
    }
    for (int i=0;i<M;i++) {
        if (f1[i]>=2) {
            printf ("0
");
            return 0;
        }
    }
    ll ans=1;
    for (int i=0;i<N;i++)
        for (int j=i+1;j<N;j++) 
            ans=ans*(abs(x[i]-x[j]))%M;
    printf ("%lld
",ans);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zhanglichen/p/12407920.html