codeforces 306 div2

来源:互联网 发布:软件开发费 编辑:程序博客网 时间:2024/05/01 17:43
A. Two Substrings
判断串里是否有不重叠的AB和BA,简单的暴力方法就是扫4遍,前两遍找AB和BA,后两遍找BA和AB,任意一种情况合法即可
#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;char str[100010];int main(){    int len;    gets(str);    len = strlen(str);    bool a1,a2;    a1 = a2 = false;    int flag1 = -1,flag2 = -1;    for(int i =0;i < len;i++){        if(str[i] == 'A' && str[i+1] == 'B'){            flag1 = i;            break;        }    }    for(int i =0;i < len;i++){        if(str[i] == 'B' && str[i+1] == 'A'){            if(i != flag1 + 1 && flag1 != i + 1){                flag2 = i;            }        }    }    if(flag1 != -1 && flag2 != -1) a1 = true;    flag1 = -1;    flag2 = -1;    for(int i =0;i < len;i++){        if(str[i] == 'B' && str[i+1] == 'A'){            flag1 = i;            break;        }    }    for(int i =0;i < len;i++){        if(str[i] == 'A' && str[i+1] == 'B'){            if(i != flag1 + 1 && flag1 != i + 1){                flag2 = i;            }        }    }    if(flag1 != -1 && flag2 != -1) a2 = true;    if(a1||a2){        cout<<"YES"<<endl;    }    else cout<<"NO"<<endl;    return 0;}




B. Preparing Olympiad

这题数据量n<=15,因此可以暴力枚举每一种存在情况,然后根据情况来判断是否合法,看到题目莫名想到了差分约束,等会补一发姿势

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;#define INF 0x3f3f3f3fint num[17];int main(){    int n,l,r,x;    cin>>n>>l>>r>>x;    for(int i = 0;i < n;i++) cin>>num[i];    int nn,ans = 0;    nn = 1<<n;    sort(num,num+n);    for(int i = 2;i < nn;i++){        int tmp = i;        int sum = 0;        int maxx = 0;        int minn = INF;        int t = 0;        for(int j = 0;j < n;j++){            if(tmp&1) {                maxx = max(maxx,num[j]);                minn = min(minn,num[j]);                sum += num[j];                t++;            }            tmp>>=1;        }        if(maxx - minn >= x && sum >= l && sum <= r && t >= 2){            ans++;        }    }    cout<<ans<<endl;    return 0;}

C. Divisibility by Eight

给一个100位的数,可以删掉某些位使得剩下这些位组成的数能够被8整除。问是否存在这种方案,如果存在则输出一组。

打了一张8000以内的8的倍数的表 


观察可以发现,这些倍数:1.都以偶数结尾 2.都包含了某些序列中的一种。 

实际上,在数字非常大的时候,假设选出某些元素可以使得可以被8整除,那么那个被8整除的数一定能再选出一些元素组成的数能够被8整除,因此只要枚举比较小的8的倍数看是否是原文的一个子串即可,如果不是则不存在。

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;#define N 10100int num[N];void init(){    num[0] = 0;    for(int i = 1;i < N;i++){        num[i] = num[i-1] + 8;    }}char str[106];int main(){    init();    int k = 1;    gets(str);    char tmp[10];    int len = strlen(str);    int flag = -1;    for(int i = 0;i < N;i++){        int nn = 0;        int tt = num[i];        while(1){            tmp[nn++] = tt%10 + '0';            tt/=10;            if(!tt) break;        }        for(int k = len,j = 0;k >=0;k--){            if(tmp[j] == str[k]){                j++;            }            if(j == nn){                flag = i;                break;            }        }        if(flag != -1) break;    }    if(flag == -1)        cout<<"NO"<<endl;    else{            cout<<"YES"<<endl;    cout<<num[flag]<<endl;    }    return 0;}

D. Regular Bridge

有一种图,每个节点的度数为k,并且至少含有一个桥。现在给出度数k,问是否存在这样一个图,如果存在则输出一个。

首先证明如果k为偶数是不存在这样的图的。

如果含有一个桥,假设断开桥之后变成了两个连通分支。假设其中一个连通分支有n个点,那么这个联通分支的点的度数和为k*n-1,当k为偶数时k*n-1为奇数,而一张图的度数必然为偶数,因此不存在。

当k为奇数的时候如何构造呢。

首先选一个点为桥的一个端点,那么这个点还需要与k-1个点相连,剩下的k-1个点互连的话度数还缺1,因此还需要再引进一个点与每一个点相连,然而此时新引进的点度数又缺1,因此再引进一个点与之相连,再将新引进的点与前k-1个点相连这两个点就满足了,而k-1个点度数超了,要重新分配,这时发现只要与其间的k-3个点相连就行了。

这样就可以构造了。

构造两个相同的连通分支然后将它们相连即可。

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;#define N 1000010struct node{    int u;    int v;}edge[N];int nn;void deal(int p,int k){     for(int i = 1;i < k;i++){        edge[nn].u = p;        edge[nn++].v = p + i;     }     int temp;     temp = (k - 3) / 2;     for(int i = 1;i < k;i++){        for(int j = 0;j < temp;j++){            edge[nn].u = p + i;            edge[nn++].v = p + (i + j)%(k - 1) + 1;        }     }     for(int i = 1;i < k;i++){        edge[nn].u = p + k;        edge[nn++].v = p + i;        edge[nn].u = p + k + 1;        edge[nn++].v = p + i;     }     edge[nn].u = p + k;     edge[nn++].v = p + k + 1;}int main(){    int k,x;    cin>>k;    if(k%2 == 0){        cout<<"NO"<<endl;    }    else if(k == 1){        cout<<"YES"<<endl;        cout<<"2 1"<<endl;        cout<<"1 2"<<endl;    }    else{    cout<<"YES"<<endl;    x = 2 * (k + 2);    deal(1,k);    deal(x/2+1,k);    edge[nn].u = 1;    edge[nn++].v = x/2+1;    cout<<x<<" "<<nn<<endl;    for(int i = 0;i < nn;i++){        printf("%d %d\n",edge[i].u,edge[i].v);    }    }    return 0;}


0 0