cf 653

来源:互联网 发布:steam网络不稳定 编辑:程序博客网 时间:2024/04/28 22:09

http://codeforces.com/contest/653/problem/A


//排序去重后判断是否有3个连续相差为1的数

#include <bits/stdc++.h>using namespace std;int a[1000];int main(){    int n;    scanf("%d",&n);    for(int i=0;i<n;i++)    {        scanf("%d",a+i);    }    sort(a,a+n);    int i=0,j=1;    while(j<n)    {        if(a[j]!=a[i])        {            swap(a[++i],a[j]);        }        j++;    }    int flag=0;    for(int k=0;k<=i-2;k++)    {        if(a[k]+1==a[k+1]&&a[k+1]+1==a[k+2])            flag=1;    }    if(flag)        puts("YES");    else        puts("NO");    return 0;}


http://codeforces.com/contest/653/problem/B


给你由a,b,c,d,e,f六个字符组成长度为n的字符串经过q中的若干个操作是否可以变成字母a

这题我们可以从后往前推,由a经过若干个操作是否可以变成长度为n的字符串  这里需要注意只能替换字符串的前两个字母



#include <bits/stdc++.h>using namespace std;vector<string>v[1000];map<string,int>mm;map<char,string>::iterator it;int n,b;void dfs(string s){    if(s.size()>n)return;    if(s.size()==n)    {        mm[s]++;       // cout<<s<<endl;    }    else    {            char c=s[0];            for(int k=0;k<v[c].size();k++)            {                s.replace(0,1,v[c][k]);                dfs(s);                s.replace(0,2,1,c);            }    }}int main(){    scanf("%d%d",&n,&b);    string s;    char c;    mm.clear();    while(b--)    {        cin>>s>>c;        v[c].push_back(s);    }    for(int i=0;i<200;i++)    {        for(int k=0;k<v[i].size();k++)        {            s=v[i][k];            c=char(i);            if(c=='a')            {                dfs(s);            }        }    }    printf("%d\n",mm.size());    return 0;}

http://codeforces.com/contest/653/problem/C


给你n个数问你有多少种方法可以交换一次序列中的a[i]  a[j] 使得序列变成nice序列 nice序列的定义为 奇数下标的a[i] <a[i+1]  偶数下标的数a[i]>a[i+1]


我们先可以遍历一遍序列找到有多少个不符合nice序列定义的数 如果a[i]不符合nice定义记录下不符合的数的下标i 和i +1  当个数大于8时 不可能经过一次交换得到nice序列 3 3 4 5 6 7  这个就刚好为吧 交换一次可以变成nice序列 如果小于8的话我们可以从记录下的下标每一个去寻找符合nice序列的数   

#include <bits/stdc++.h>using namespace std;const int maxn=150010;const int inf=(1<<30);int a[maxn];int mark[maxn];int cn;//由于序列的其他位置都符合nice的定义只有记录下来的个数不符合 所以交换后只需判断是否全部都符合定义就可以了int check(){    int flag=0;    for(int i=0;i<cn;i++)    {        int t=mark[i];        if(t%2==0&&a[t-1]<a[t]&&a[t]>a[t+1])            flag++;        else if(a[t-1]>a[t]&&a[t]<a[t+1])            flag++;    }    return flag==cn?1:0;}int main(){    int n;    scanf("%d",&n);    a[0]=inf;    memset(mark,-1,sizeof(mark));    for(int i=1;i<=n;i++)        scanf("%d",a+i);    a[n+1]=n%2?inf:0;    cn=0;    for(int i=1;i<n;i++)    {        if(i%2==1)        {            if(a[i]>=a[i+1])            {                mark[cn++]=i;                mark[cn++]=i+1;            }        }        else        {            if(a[i]<=a[i+1])            {                mark[cn++]=i;                mark[cn++]=i+1;            }        }    }    if(cn>8)        puts("0");    else    {        int res=0;        int flag=0;        map<pair<int,int>,int>m; //记录交换的数防止重复交换        m.clear();        for(int i=0;i<cn;i++)        {            for(int k=1;k<=n;k++)            {                flag=0;                int t=mark[i];                swap(a[t],a[k]);                if(k%2==1&&a[k-1]>a[k]&&a[k]<a[k+1]&&check())                {                    if(m[make_pair(t,k)]==1||m[make_pair(k,t)]==1)                        flag=0;                    else                        flag=1;                    m[make_pair(t,k)]=1;                    m[make_pair(k,t)]=1;                }                if(k%2==0&&a[k-1]<a[k]&&a[k]>a[k+1]&&check())                {                    if(m[make_pair(t,k)]==1||m[make_pair(k,t)]==1)                        flag=0;                    else                        flag=1;                    m[make_pair(t,k)]=1;                    m[make_pair(k,t)]=1;                }                if(flag)                    res++;                swap(a[k],a[t]);            }        }        printf("%d\n",res);    }    return 0;}




0 0