南华大学第十五届ACM程序设计竞赛(重现赛)

在某华大学里有一个无聊的群组,群内的所有成员都是复读机,他们疯狂复读着别人的消息。然而复读机们在群内也是有阵营的,一个阵营的复读机会根据心情选择是否复读同一个阵营的成员的消息,但绝对不会去复读其他阵营的消息。

        群内有n个人(标号1-n号)。现在群内聊天记录中一共有m条消息。请根据这些消息,判断出如果群内第i号成员(1<=i<=n)发一条十分有趣的消息,在同一阵营的成员都会去复读这条消息情况下,那么这条消息会被复读几次?

如果无法判断i号成员和j号成员是否为同一阵营,则视为不同阵营。

输入描述:

输入包括m+1行。第一行包括两个整数n,m;其后的m行为当前的聊天记录,每行包括一个数字i和一个字符串s(表示i发了一条消息)。(保证1<=i<=n,m<=100000,消息的字符串总长不超过100000)

输出描述:

输出一行,包括n个数字。第i个数字表示第i号成员的有趣消息会被复读几次(1<=i<=n)。数字与数字之间用一个空格分隔。

示例1

输入

复制

3 5

1 a

2 a

1 b

2 c

3 c

输出

复制

2 2 2

说明

对于样例1: 由聊天记录的前两行可以得出2号和1号为同一阵营,由最后两行可得3号和2号为同一阵营,所以三者为同一阵营,他们三个发送的消息会被复读2次,故输出为2 2 2;

示例2

输入

复制

3 3

1 a

2 b

3 c

输出

复制

0 0 0

说明

对于样例2:1,2,3号无法判断是否为同一阵营,视为不同阵营。

备注:

对于复读的概念:

若聊天记录为

1 a

2 a

3 a

属于2,3号复读了1号的消息。

若聊天记录为

1 a

2 b

3 a

不构成任何复读,1的‘a‘和3的‘a’均属于自己原创消息。

Ac代码
#include
#include
#include 
int per[100005];
int num[100005];
using namespace std;
int search_root(int root)
{
    int son=root;
    int temp;
    while(per[root]!=root){
        root=per[root];
    }
    while(son!=root){
        temp=per[son];
        per[son]=root;
        son=temp;
    }
    return root;
}
int main()
{
    int n,m;
    int i,j;
    int x,y;
    int root1,root2;
    string a,b;
    while(scanf("%d%d",&n,&m)!=EOF){
        for(i=0;i<=n;i++){
            per[i]=i;
        }
        memset(num,0,sizeof(num));
        y=0;
        b="";
        while(m--){
            cin>>x>>a;
            if(a==b){
                root1=search_root(x);
                root2=search_root(y);
                if(root1!=root2){                  //如果不相同,一定要更新
                 per[root1]=root2;
                }
                b=a;
                y=x;
            }
            else{
                b=a;
                y=x;
            }
        }
        int root;
        for(i=1;i<=n;i++){
            root=search_root(i);
            num[root]++;
        }
        for(i=1;i<=n;i++){
            root=search_root(i);
            if(i==1)printf("%d",num[root]-1);
            else printf(" %d",num[root]-1);
        }
        printf("\n");
    }
}
    

 某华大学小飞中奖了!!!奖品是一张免费飞机票,唯一遗憾的是,这张飞机票有限定区间,需要从k个区间中选择其一。小飞打算高高兴兴的出去玩啦,但是,从s地出发,去往e地,可能没有直达的飞机票,可能需要转机(所有飞机线路都是无向的),小飞毕竟是个学生党,出去玩首先得考虑省钱,所以,小飞遇到麻烦了,请帮小飞计算最便宜的一条路线,小飞会很感激你的。

输入描述:

第一行为三个整数n,s,e,n表示n个不同城市的飞机场,s为出发点,e为目的地。(1<=n<=1000,  1<=s,e<=n)

第二行为一个整数m,表示m条普通飞机线路,接下来的m行描述每条线路,每行包含三个整数a、b、c,a、b代表普通飞机线路两端,c表示价格。(1<=m<=1000,  1<=a,b<=n,  1<=c<=1000)

接下来的一行为一个整数k,表示k个免费机票的航线区间, 然后k行来描述每条免费航线,每行两个整数a’、b’,    分别代表免费航线两端。(1<=k<=1000,  1<=a’,b’<=n)

输出描述:

每个测试数据有两行输出,第一行为是否使用免费飞机票,是则输出“Yes”,否则输出“No”。第二行输出总共花费。

in

4 1 4

3

1 2 1

1 3 2

2 4 3

1

3 4

Out

Yes

2

 

题解

首先敲出模板,然后在更具免费机票进行更新,值得注意的是更新完以后记得复原。但是每次都更新的话就会超时。

所以对他的起点和终点进行迪杰斯特拉。然后更新的话的就当与免费机票的 位置+终点+起点的距离。

#include
#include
#include 
using namespace std;
#define maxpath 1050
#define maxdis 10e7
int G[maxpath][maxpath];
int n,s,e;
void djs(int v,int path[])
{
    int i,j;
    int vis[maxpath];
    int x;
    memset(vis,0,sizeof(vis));
    for(i=1;i<=n;i++){
        path[i]=G[v][i];
    }
    for(i=1;i<=n;i++){
        int Min=10e7;
        for(j=1;j<=n;j++){
            if(vis[j]==0&&path[j]

 从前有个小哥哥Bill非常喜欢编程,但是让他更加心动的是班上那位小姐姐,为了取得小姐姐的欢心,Bill每天刷acm题,只想着找一个机会大发雄威。机会来了!有一天,老师为了提高同学们学习数学的积极性,做了一个小游戏:六位同学分为一组,每个同学心中想着自己最喜欢的数字a,b,c,e,f,g,对于(ax+by+cz)的k次方展开式中,(x^e)(y^f)(z^g)的系数是多少,当游戏开始时参与游戏的人需要在1秒内报出结果是多少。Bill一时兴奋忘了拿电脑,你能在下面帮助他赢得女神的欢心么?

 

输入
输入包含7个整数,分别为a ,b ,c, k ,e ,f, g每两个整数之间用一个空格隔开。(0≤k≤1,000, 0≤e,f,g≤k,且e+f+g=k ,0 ≤a,b,c ≤1000000)

 

输出

输出一行,包含一个整数,表示所求的系数,这个系数可能很大,输出对10007取模后的结果。

输入

3 2 1 4 1 2 1

输出

144

注:是说在展开式中的系数,则可以用二项式定理。注意是展开式中

/**

因为x,y,z是未知数,也就意味着只要知道幂符合就可可以了,然后结合二次项定理就可以了。

即c*z=C

但z^g和上面的公式不冲突

(ax+by+cz)^k <===> (A+B+C)^k <====> ((A+B)+C)^k

<===>  (A+B)^k + C[k,1](A+B)^(k-1)*C + C[k,2](A+B)^(k-2)*C^2 + C[k,3](A+B)^(k-3)*C^3 + ... + C^k

当C的为 g 时,我们的答案为 C[k,g](A+B)^(k-g)*C^g

对(A+B)^(k-g)再次二项次展开,当B的项数为f时: ==> C[k-g,e]A^(k-g-f)*B^f

最终答案:C[k,g]*C[k-g,e]*A^e*B^f*C^g

**/

#include
using namespace std;
int mod=10007;
int N = 1001;
int C[1007][1007];
void init(){ /// 求组合数
    for(int i=0;i>1;
    }
    return ans%mod;
}
int main()
{
    int a ,b ,c, k ,e ,f, g; //(ax+by+cz)^k <===> (A+B+C)^k <====> ((A+B)+C)^k
    init();
    while(scanf("%d%d%d%d%d%d%d",&a,&b,&c,&k,&e,&f,&g)!=EOF){
        printf("%d\n",(((((C[k][g]%mod*C[k-g][e]%mod)%mod*pow(a,e))%mod*pow(b,f))%mod)*pow(c,g))%mod);
    }
}

 

你可能感兴趣的:(acm_牛客网)