Codeforces Round #773 (Div. 2)

Posted on 2022-02-25 12:30  Capterlliar  阅读(40)  评论(0编辑  收藏  举报

A - Hard Way

题意:给出三角形三个顶点的坐标(均为整数),称无法连一条直线到x轴而不通过三角形内部的边是unsafe的,求这个三角形unsafe的边长之和。

解:显然和y轴平行且另一个顶点在其下方的边是unsafe的。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define maxx 200005
#define maxn 1005
#define maxm 200005
#define eps 0.00000001
#define inf 0x7fffffff
#define mod 998244353
//#define int long long
int n,m,k,q;
int x[3],y[3];
signed main() {
    int T;
    scanf("%d",&T);
    while(T--){
        for(int i=0;i<3;i++)
            scanf("%d%d",&x[i],&y[i]);
        int ans=0;
        if(y[0]==y[1]&&y[1]>y[2])
            ans= abs(x[0]-x[1]);
        else if(y[1]==y[2]&&y[2]>y[0])
            ans= abs(x[1]-x[2]);
        else if(y[0]==y[2]&&y[2]>y[1])
            ans= abs(x[0]-x[2]);
        printf("%d\n",ans);
    }
    return 0;
}
View Code

B - Power Walking

题意:给出n个数,将其任意分为k组,令f(x)为第x组不同的数的个数,分别求k=1,2,3,...,n时,f(1)+...+f(k)的值。

解:最后答案和重复的数相关。假设这串数为111222333,k=1时,只有一种分法,答案为3;k=2时,将1独立出去,答案还是3;k=3时,123各自独立,答案为3;k=4时,有一个集合不得不有两个数了,答案为4;k=n时,答案为n。综上,假设集合中有x种不同的数,当k<=x时,答案为x;当k>x时,答案为k。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define maxx 200005
#define maxn 1005
#define maxm 200005
#define eps 0.00000001
#define inf 0x7fffffff
#define mod 998244353
//#define int long long
int n,m,k,q;
signed main() {
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        set<int> s;
        int t;
        for(int i=1;i<=n;i++){
            scanf("%d",&t);
            s.insert(t);
        }
        for(int i=1;i<=s.size();i++)
            printf("%d ",s.size());
        for(int i=s.size()+1;i<=n;i++)
            printf("%d ",i);
        printf("\n");
    }
    return 0;
}
// 111222333444555666
// 1 6 2 6 3 6 4 6 5 6 6 6 7 7 8 8
//111 222 333 444 5556 66
View Code

C - Great Sequence

题意:给出n个数和x,可以以任意方式排列。求最小添加多少个数,可以使得对于每一个a2i,都有a2i*x=a2i+1.

解:有a2i*x的时候,取这个数;没有就添一个。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define maxx 200005
#define maxn 1005
#define maxm 200005
#define eps 0.00000001
#define inf 0x7fffffff
#define mod 998244353
//#define int long long
int n,x;
signed main() {
    int T;
    scanf("%d",&T);
    while(T--){
        map<ll,int> m;
        scanf("%d%d",&n,&x);
        int t;
        for(int i=1;i<=n;i++){
            scanf("%d",&t);
            m[t]++;
        }
        ll ans=0;
        for(auto [now,num]:m){
            for(int i=0;i<num;i++){
                if(m[now*x])
                    m[now*x]--;
                else ans++;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}
View Code

D. Repetitions Decoding

题意:给出一串数,每次可以在任意位置添加任意相同的两个字母。求一种方法(操作数不一定要最少),使得这串数能分成若干段,其中每一段都能分成两个相同的子数组。

解:构造题。首先每个数字要出现偶数次,不然怎么加都是奇数,不可能平分。先观察样例,比如123321,可以通过在中间添加两个2,再加两个1。获得方法:当这串数对称时,可以在中间连续加;当它不对称时,如122313,可以按上述方法在1后面加两个2,为了写起来简单,不判断是否原来有连续两个2,再加两个,最后在中间加两个3,这样有一对对称了。按这个方法连续处理,可以证明能处理完,并且对称的情况也适用。However,这玩意到底该怎么写。。。。

先膜一下大佬的写法。由于每次增加两个数,但其实我们只用它的一半,另一半刚好是它的反转。所以写的时候不用插入,而是删除和反转。然后就很好写了。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define maxx 200005
#define maxn 1005
#define maxm 200005
#define eps 0.00000001
#define inf 0x7fffffff
#define mod 998244353
//#define int long long
int n,x;
signed main() {
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        vector<int> a;
        map<int,int> m;
        int t;
        for(int i=0;i<n;i++){
            scanf("%d",&t);
            a.push_back(t);
            m[t]++;
        }
        int flag=0;
        for(auto [x,y]:m){
            if(y%2){
                printf("-1\n");
                flag=1;
                break;
            }
        }
        if(flag)
            continue;
        vector<pair<int,int> > ans1;
        vector<int> ans2;
        int cnt=0;
        for(int i=1;i<=n/2;i++){
            auto it=++a.begin();  //不能是a.begin()++
            while(*it!=*a.begin())
                it++;
            int t=it-a.begin();
            for(int j=1;j<=t-1;j++)
                ans1.push_back(make_pair(cnt+j+t,a[j]));
            reverse(a.begin()+1,a.begin()+t);
            a.erase(it);  //先删it,不然迭代器会错位
            a.erase(a.begin());
            cnt+=t*2;
            ans2.push_back(t*2);
        }
        printf("%d\n",ans1.size());
        for(auto [x,y]:ans1)
            printf("%d %d\n",x,y);
        printf("%d\n",ans2.size());
        for(auto i:ans2)
            printf("%d ",i);
        printf("\n");
    }
    return 0;
}
//  abba -> abaaba
// abcddcba -> abcdabcddcbadcba
// ac -> acaa -> acac ca
// abc -> -1
// abdabd dbcdbc cbbcbb bb -> abdabd dbcdbc
// addcbcaddcbc cbcddb -> addcbca dd b
// addcbcab -> addcbcaddcbc cbcddb
// 1313 32232222
//3211232112 211211 11
View Code