Codeforces805

A.Fake NP

题意:给定两个整数L R,求[L,R]中公因子不为1的数的最大个数。

题解:显然要想数量尽量多,公因子就不会很大,所以枚举公因子(素数)即可,注意特判L==R的情况

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

const int P[]={2,3,5,7,11,13,17,23,29,0};
int L,R,X,S;

int main(){
    cin >> L >> R;
    if(L==R){
        cout << L << endl;
        return 0;
    }

    for(int i=0,c;P[i];i++){
        c=(R-L)/P[i];
        if(L%P[i]==0) c++;

        if(c>S) S=c,X=P[i];
    }
    cout << X << endl;

    return 0;
}
View Code

B.3-palindrome

题意:给定N,求长度为N,仅由a b c构成,不含长度为3的回文子串,含最少c的字符串。

题解:显然由aabb为循环节的字符串符合条件

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

int N;

int main(){
    cin >> N;
    for(int i=1;i<=N;i++){
        if(i%4==1 || i%4==2) cout << 'a';
        else cout << 'b';
    }
    cout << endl;

    return 0;
}
View Code

C.Find Amir

题意:有N个节点标号1-N,连接两个节点的花费为(i+j)%(N+1),求所有节点联通的最小花费。

题解:显然i与N-i+1要相连,除此之外的节点连接都会产生花费,显然i与N-i+2相连可以将两“对”联系起来,注意特判N为1的情况。

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

int N;

int main(){
    cin >> N;
    if(N<=2){
        cout << 0 << endl;
        return 0;
    }

    cout << (N/2-1)+N%2 << endl;

    return 0;
}
View Code

D.Minimum number of steps

题意:给定一个仅由a b构成的字符串,每次可将一个字串'ab'变为'bba',求字符串中不含'ab'所需要的操作次数。

题解:显然最后的字符串为b……ba……a的形式,注意到对于一个位置,后面的字母并不会对前面的答案产生影响,注意到b……ba……ab变为合法的话,仅与b之前有多少个a有关,且操作次数为2^(a的数量)-1。

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long

const ll P=1e9+7;
const int MAXL=1000000+2;
ll C,Ans;
char S[MAXL];

ll QuickPow(ll a,ll b){
    ll t=(b&1?a:1);
    while(b>>=1){
        a=a*a%P;
        if(b&1) t=t*a%P;
    }
    return t;
}

int main(){
    cin >> S;
    for(int i=0;S[i];i++)
        if(S[i]=='a') C++;
        else Ans=(Ans+QuickPow(2,C)-1+P)%P;
    cout << Ans << endl;

    return 0;
}
View Code

E.Ice cream coloring

题意:给定一颗树,树的每个节点有一个点权集,另给一个图,图中两点i j相连当且仅当树中某个节点的点权集同时含i j,求将图染成:相邻两点颜色不同,所需要的最小花费。(保证一个值在树上构成一个联通的子图)

题解:注意到最后的保证,那么我们得到的图实际上是许多联通块连在一起,因此在一个联通块内可以从头标号(在不与相连节点的标号冲突的前提下)。

代码:

#include <queue>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN=300000+2;
struct HASH{
    int u;
    HASH *next;
    HASH(){}
    HASH(int _u,HASH *_next):u(_u),next(_next){}
}*tab[MAXN],*rec[2][MAXN],mem[3*MAXN];
int N,M,C,Ans=1,c[MAXN];
queue<int> q[MAXN];

void DFS(int x,int f){
    int t=1;
    for(HASH *p=rec[0][x];p;p=p->next){
        if(!c[p->u]){
            if(!q[x].empty() && t==q[x].front()) q[x].pop(),t++;
            c[p->u]=t;

            for(HASH *r=rec[1][p->u];r;r=r->next) q[r->u].push(t);
        }
    }

    for(HASH *p=tab[x];p;p=p->next)
        if(p->u!=f) DFS(p->u,x);
}

int main(){
    cin >> N >> M;
    for(int i=1,s;i<=N;i++){
        cin >> s,Ans=max(Ans,s);
        for(int j=1,x;j<=s;j++){
            cin >> x;
            rec[0][i]=&(mem[C++]=HASH(x,rec[0][i]));
            rec[1][x]=&(mem[C++]=HASH(i,rec[1][x]));
        }
    }
    for(int i=1,u,v;i<N;i++){
        cin >> u >> v;
        tab[u]=&(mem[C++]=HASH(v,tab[u]));
        tab[v]=&(mem[C++]=HASH(u,tab[v]));
    }

    DFS(1,0);
    cout << Ans << endl;
    for(int i=1;i<=M;i++) cout << (c[i]?c[i]:1) << " ";
    cout << endl;

    return 0;
}
View Code

F.Expected diameter of a tree

(待补)

猜你喜欢

转载自www.cnblogs.com/WDZRMPCBIT/p/10539222.html