Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) 菜鸡只会ABC!

                Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1)

                                                           全场题解


   菜鸡只会A+B+C,呈上题解:

   

                                                           A. Bear and Big Brother 

   题意:我也没看太清,就是给你两个10以内的数a,b。a每天乘以3,b每天乘以2,求多少天后a大于b。

   思路:应该是有公式的,不过看到数据这么小直接暴力乘求解。官方题解貌似就是这样,数据小就是水题。

const int N=1e3+10;
int main()
{
    int a,b;
    while(~scanf("%d%d",&a,&b))
    {
        if(a>b) puts("0");
        else if(a==b) puts("1");
        else
        {
            for(int i=1;;i++)
            {
                a*=3,b*=2;
                if(a>b) {printf("%d\n",i);
                break;}
            }
        }
    }
}


                                   B. Bear and Friendship Condition

    题意:如果一个人a与b是好朋友,b又和c是好朋友,那么a和c也应该是好朋友,否则输出NO。现在给你人数n,m种关系,判断YES or NO!

    思路:被题解误导了一下,一上午没做出来,中午打会球回来秒A了。这种关系是可以传递的,我们可以用并查集将有关联的集结起来,然后求出每个集合的人数。题目说不会有重边,那么在输出的时候可以求出每个人与多少个人是好朋友,那么假如一个集合的人数为k,那么这k个人肯定要和其余k-1个人是好朋友啊,直接判断就行了。题解给的dfs可能我dfs不是很擅长。

const int N=150000+10;
int n,m,f[N],num[N],sum[N];
int find(int x)
{
    return f[x]==-1?x:f[x]=find(f[x]);
}
void solve()
{
    memset(sum,0,sizeof(sum));
    for(int i=1;i<=n;i++)
    {
        int x=find(i);
        sum[x]++;
    }
    for(int i=1;i<=n;i++)
    {
        int x=find(i);
        if(num[i]!=sum[x]-1)
        {
            puts("NO");
            return ;
        }
    }
        puts("YES");
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        memset(num,0,sizeof(num));
        memset(f,-1,sizeof(f));
        int u,v;
        for(int i=0; i<m; i++)
        {
            scanf("%d%d",&u,&v);
            int uu=find(u),vv=find(v);
            if(uu!=vv) f[uu]=vv;
            num[u]++,num[v]++;
        }
        solve();
    }
    return 0;
}


                                        C. Bear and Different Names

  怎么感觉C题比B题还简单,挺有意思的,一个模拟构造就行了。

  题意:n个人排成一列,每连续k个人组成一个团,一个团的战斗力高要求这k个人姓名都不相同,否则这个团的战斗力低。现在给你1到n-k+1这些团战斗力高低之分,要你找到符合条件的这n个人的名字。数据50以内。

  思路:我们可以观察到两个相邻的图只有最前面的那个人与最后面的名字不同,也就是说重复了k-2个人。那么我们可以初始化n个互不相同的字符串(从A开始计数即可).如果当前团是NO,说明有重复的,我们直接让最后一个人的名字等于最前一个人的就行了,下一个团就不包括最前一个人了。这样只要是NO的只需把当前团最后一个人的名字改成当前团最前那个人的就行了。

string s[55]={"0","A", "B", "C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
"Aa","Ab","Ac","Ad","Ae","Af","Ag","Ah","Ia","Ja","Ka","La","Ma","Na","Oa", "Pa", "Qa", "Ra","Sa","Ta","Ua","Va","Wa", "Xa","Ya","Za" }; 
string str,ans[52];
int main() 
{
	int n,k;
	while(~scanf("%d%d",&n,&k))
	{
		for(int i=1;i<=n;i++)
		ans[i]=s[i];
		for(int i=1;i<=n-k+1;i++)
		{
			cin>>str;
			if(str[0]=='N')	ans[i+k-1]=ans[i];
		}
		for(int i=1;i<=n;i++)
		cout<<ans[i]<<" ";
		cout<<endl;
	}
	return 0;
} 

   D题又是一个树搜索,让我这种菜鸡情何以堪1!!!!11



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值