Codeforces Round #170 (Div. 2)总结

17 篇文章 0 订阅

因为昨天没有网络,只能今天补做。

A题:

       题意是给你相邻2个点的距离,最后点的距离为最后一个到第一个的距离(环状)。给你起点和终点,让你求最短路径。

       这个题比较简单吧,要不就是起点到终点,要不就是终点到起点,2种取最小值即可。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#define MAX 101
using namespace std;
int a[MAX],sum[MAX];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
	sum[0]=0;
	for(int i=1;i<=n;i++)
	{
	    scanf("%d",&a[i]);
	    sum[i]=sum[i-1]+a[i];
	}
	int a,b;
	scanf("%d%d",&a,&b);
	if(a>b)
	    swap(a,b);
	int ansa=sum[b-1]-sum[a-1];
	int ansb=sum[n]-sum[b-1]+sum[a-1];
	printf("%d\n",min(ansa,ansb));
    }
    return 0;
}


B题:

大意是说给你n个字符串,你需要找一个满足最短最小的字典序并且其不能在这n个字符串中出现过(包括n个字符串中的子串)。我用DFS过的,最开始DFS时len那没处理好,忘了return。还是比较好懂。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
char str[1001],st[30];
bool use[27];
int len=1,flag;
void DFS(int cou)
{
    if(flag)
	return;
    while(1)
    {
	for(int i=0;i<26;i++)
	{
	    st[cou]=i+'a';
	    if(cou+1<len)
		DFS(cou+1);
	    else if(!strstr(str,st))
	    {
		printf("%s\n",st);
		flag=1;
		return;
	    }
	    if(flag)
		return;
	}
	if(cou==0)
	   len++;
	else
	    return;
    }
}
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
	memset(use,0,sizeof(use));
	flag=0;
	int cou=0;
	for(int i=0;i<n;i++)
	{
	    char ita[30];
	    scanf("%s",ita);
	    for(int j=0;j<strlen(ita);j++)
	    {
		str[cou++]=ita[j];
		use[ita[j]-'a']=1;
	    }
	    str[cou++]=' ';
	}
	len=1;
	DFS(0);
    }
    return 0;
}

C题:

            大意就是有N个人,他们每个人都会相应的语言,也可能一门语言都不会。现在公司要跟他们进行培训,使得所有的人都能够相互进行交流(即不存在独门语言)要求求最少的花费(每个培训花费1)。

    我的解题方法是先将所有的语言和人进行建图操作,即每个人和语言作为一个独立的点,然后找到图中共有K个组别,最后的答案就应该是k-1,但是如果所有的人都不会任何语言的话,答案就应该是n。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#define MAX 201
using namespace std;
int n,m,p[MAX];
bool use[MAX];
int find(int x)
{
    if(p[x]==x)
	return x;
    return p[x]=find(p[x]);
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
	for(int i=0;i<MAX;i++)
	    p[i]=i;
	int count=0;
	for(int i=1;i<=n;i++)
	{
	    int k;
	    scanf("%d",&k);
	    if(!k)
		count++;
	    int ita=find(i);
	    for(int j=0;j<k;j++)
	    {
		int a;
		scanf("%d",&a);
		a+=n;
		int itb=find(a);
		p[itb]=ita;
	    }
	}
	if(count==n)
	{
	    printf("%d\n",n);
	    continue;
	}
	for(int i=1;i<=n+m;i++)
	    find(i);
	int ans=0;
	for(int i=1;i<=n;i++)
	    if(!use[p[i]])
	    {
		use[p[i]]=1;
		ans++;
	    }
	printf("%d\n",ans-1);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值