2020多校第八场

2020多校第八场(南昌理工ACM集训队)

1003

#include <bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
typedef long long ll;
const int INF=0x3f3f3f3f;
int main(){
    
    
    int t;
    scanf("%d",&t);
    while(t--){
    
    
        double x1,y1,x2,y2,x3,y3;
        scanf("%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3);
        double b = y1-(y1-y3)/(x1-x3)*x1;
        if((y1-y3)/(x1-x3)>0){
    
    
            if(y3>y1&&x3>x1&&(y2-(y1-y3)/(x1-x3)*x2-b)>0){
    
        //a在下 
                printf("Clockwise\n");
                continue;
            }
            if(y3<y1&&x3<x1&&(y2-(y1-y3)/(x1-x3)*x2-b)<0){
    
    
                printf("Clockwise\n");
                continue;
            }
        }else if((y1-y3)/(x1-x3)<0) {
    
    
            if(y3>y1&&x3<x1&&(y2-(y1-y3)/(x1-x3)*x2-b)<0){
    
    
                printf("Clockwise\n");
                continue;
            }
            if(y3<y1&&x3>x1&&(y2-(y1-y3)/(x1-x3)*x2-b)>0){
    
    
                printf("Clockwise\n");
                continue;
            }
        }
        if((y1-y3)/(x1-x3)==0){
    
    
            if((x2-x1)>0&&y3<y1&&x3<x1){
    
    
                printf("Clockwise\n");
                continue;
            }
            if((x2-x1)<0&&y1<y3&&x1<x3){
    
    
                printf("Clockwise\n");
                continue;
            }
        }
        printf("Counterclockwise\n");
    }
    return 0;
}

1006

思路:先正着更新一遍再倒着更新一遍
用x[i]记录第i段的起始位置,用y[i]记录末位置
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
typedef long long ll;
inline ll read()
{
    
    
    ll s=0,w=1;char ch=getchar();
    while(ch<48||ch>57){
    
    if(ch=='-')w=-1;ch=getchar();}
    while(ch>=48&&ch<=57)s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
    return s*w;
}
int x[N],y[N],t,n,k;
bool f;
int main()
{
    
    
    t=read();
    while(t--)
    {
    
    
        f=0;
        n=read(),k=read();
        for(int i=0;i<n;i++)x[i]=read(),y[i]=read();
        for(int i=1;i<n;i++)
        {
    
    
            x[i]=max(x[i],x[i-1]-k);
            y[i]=min(y[i],y[i-1]+k);
            if(y[i]<x[i])
            {
    
    
                f=1;
                break;
            }
        }
        if(f)cout<<"NO\n";
        else
        {
    
    
            cout<<"YES\n";
            for(int i=n-1;i>0;i--)
            {
    
    
                x[i-1]=max(x[i-1],x[i]-k);
                y[i-1]=min(y[i-1],y[i]+k);
            }
            for(int i=0;i<n-1;i++)cout<<x[i]<<' ';
            cout<<x[n-1]<<endl;
        }
    }
    return 0;
}

1008

思路:找规律
n=3时,答案可以是324213162651546432
在这里插入图片描述
n=4时,答案可以是324242131316262651515464643532321653
在这里插入图片描述
n=5时,答案可以是324242421313131626262651515154646464353532324213162651546432
在这里插入图片描述
可以发现每次输出最外面2层,可以用dfs(n-2)再继续输出

#include<iostream>
using namespace std;
int t,n;
void dfs(int x)
{
    
    
    if(x==2)
    {
    
    
        cout<<"321653\n";//注意这里要变成这个,而不是样例里的答案
        //因为我用的顺序和题目样例的不一样
        return;
    }
    if(x==3)
    {
    
    
        cout<<"324213162651546432\n";
        return;
    }
    //6条边,分段输出
    //可以多举几个例子就会发现规律了
    cout<<"32";
    for(int i=1;i<=x-2;i++)cout<<"42";
    cout<<'1';
    for(int i=1;i<=x-2;i++)cout<<"31";
    cout<<'6';
    for(int i=1;i<=x-2;i++)cout<<"26";
    cout<<'5';
    for(int i=1;i<=x-2;i++)cout<<"15";
    cout<<'4';
    for(int i=1;i<=x-2;i++)cout<<"64";
    cout<<'3';
    for(int i=1;i<=x-3;i++)cout<<"53";
    cout<<'2';
    dfs(x-2);
}
int main()
{
    
    
    cin>>t;
    while(t--)
    {
    
    
        cin>>n;
        dfs(n);
    }
    return 0;
}

1009

思路:由于题目时间限制为8000ms,所以可以考虑暴力,但要减枝;
既然要把字符串分为n/k个子串,那么每个子串中都要包含原s串里出现过的每种字符,因此,统计s串中不同种类字符的个数,取他们共同的最大公因数m,
再枚举m的因数作为子串个数(这样就保证了每种字符都平均的分配到每个子串中,这样子串两两之间才有互为循环同构的可能),
然后利用kmp算法判断n/k个子串是否两两之间为循环同构(以第一个子串为主串),注意k>1与字符种类数为1的情况要特判。
为什么要用kmp呢?
因为把第一段重复一段
比如第一段为asdfg
要比较的为sdfga
把第一段变为asdfgasdfg
再用kmp就行了

#include<bits/stdc++.h>
using namespace std;
const int N=5e6+5; 
int n,t;
int kmp(string S,string T)//kmp模板
{
    
    
    int Slen,Tlen,Next[T.length()+10];
    Slen=S.length(),Tlen=T.length();
    int i,j=-1;
    Next[0]=-1;
    for(i=1;i<Tlen;i++){
    
    
        while(j>-1&&T[j+1]!=T[i])
            j=Next[j];
        if(T[j+1]==T[i])
            j++;
        Next[i]=j;
    }
    j=-1;
    for(i=0;i<Slen;i++){
    
    
        while(j>-1&&T[j+1]!=S[i])
            j=Next[j];
        if(T[j+1]==S[i])
            j++;
        if(j==Tlen-1)return 1;
    }
    return 0;
}
map<int,int>vis,num;
int k;
bool p,f;
string s;
int main()
{
    
    
    cin>>t;
    while(t--)
    {
    
    
        int m;
        k=0;
        vis.clear();
        num.clear();//清零
        scanf("%d",&n);
        cin>>s;
        if(n==1)//n=1时特判
        {
    
    
            cout<<"No\n";
            continue;
        }
        for(int i=0;i<n;i++)
        {
    
    
            num[s[i]]++;//每个元素出现的次数
            if(!vis[s[i]])
            {
    
    
                vis[s[i]]=1;
                k++;//有多少个元素
            }
        }
        p=0,f=0;
        if(k==1){
    
    cout<<"Yes\n";continue;} 
        //如果只有一种元素,显而易见输出yes
        for(auto &it:num)
        {
    
    
            int i=it.second;
            if(!p)m=i;
            else
            {
    
    
                m=__gcd(m,i);//求最大公因数
                if(m==1)break;
            }
            p=1;
        }
        for(int i=2;i<=m;i++)
        {
    
    
            if(n%i)continue;
            string ss=s.substr(0,n/i);
            ss+=ss;//把第一段补一段
            for(int j=2;j<=i;j++)
            {
    
    
                if(kmp(ss,s.substr(n/i*(j-1),n/i)))
                {
    
    
                    f=1;
                    break;//但凡有一个符合条件直接跳出输出yes
                }
            }
            if(f)break;
        }
        if(f)cout<<"Yes\n";
        else cout<<"No\n";
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_46001550/article/details/108021819
今日推荐