Codeforces Round #368 (Div. 2) A(水题) B(枚举 思维) C(数论 勾股数)

传送门:A. Brain's Photos

题意:给你一个n*m的矩阵,矩阵内包含五种字符'C', 'M', 'Y', 'W', 'G' or 'B'. 

            只有W.G.B的字符的时候输出"#Black&White",否则输出"#Color" 

思路: 直接搞 

这题好多人题目没看清,少判断了一个G,结果我的房间的人全被我hack了。。。

#include <bits/stdc++.h>
using  namespace  std;

int  main(){
  int n,m;
  while(~scanf("%d%d",&n,&m)){
    char ch;
    int flag=1;
    for(int i=0; i<n; i++){
      for(int j=0; j<m; j++){
        scanf(" %c",&ch);
        if(ch=='C'||ch=='M'||ch=='Y')flag=0;
      }
    }
    if(flag)puts("#Black&White");
    else puts("#Color");
  }
  return 0;
}

传送门:B. Bakery

题意:
n个城市,m条双向路

n个城市中有k个城市中有仓库

现在要在一个没有仓库的城市开一家面包店,使得该面包店能够至少到达一个仓库,且到达该仓库的距离尽可能小

问最小距离为多少,若没有城市适合开设面包店,则输出"-1"

思路:

我们只要把有仓库的城市标记,枚举所有边,如果某条双向路一端连着有仓库的城市,另一端连着没有仓库的城市,那就把这条路的长度取来作比较,留下距离最短的路即可

#include <bits/stdc++.h>
using  namespace  std;
const int inf=0x3f3f3f3f;
const int N=1e5+10;
bool vis[N];
int u[N],v[N],l[N];
int main()
{
    int n,m,k,i,a,ans=inf;
    scanf("%d%d%d",&n,&m,&k);
    for(i=0;i<m;i++)
        scanf("%d%d%d",&u[i],&v[i],&l[i]);
    for(i=0;i<k;i++)
    {
        scanf("%d",&a);
        vis[a]=true;
    }
    for(i=0;i<m;i++)
        if(vis[u[i]]&&!vis[v[i]]||!vis[u[i]]&&vis[v[i]])
            ans=min(ans,l[i]);
    if(ans!=inf)
        printf("%d\n",ans);
    else
        puts("-1");
    return 0;
}

传送门:C. Pythagorean Triples  

题意:

  给你一个数,构造其余两个勾股数。任意一组答案即可,没法构造输出-1.

  答案long long 范围。

思路:

  这里贴一下勾股数的构造:

  当a为大于1的奇数2n+1时,b=2n 2+2n, c=2n 2+2n+1。
  实际上就是把a的平方数拆成两个连续自然数,例如:
  n=1时(a,b,c)=(3,4,5)
  n=2时(a,b,c)=(5,12,13)
  n=3时(a,b,c)=(7,24,25)
  当a为大于2的偶数2n时,b=n 2 -1, c=n 2 +1
  也就是把a的一半的平方分别减1和加1,例如:
  n=2时(a,b,c)=(4,3,5)
  n=3时(a,b,c)=(6,8,10)
  n=4时(a,b,c)=(8,15,17)
  n=5时(a,b,c)=(10,24,26)
  n=6时(a,b,c)=(12,35,37)
可以看出n>=3,肯定可以构造至少一组勾股数,就不需要勾股定理什么的再来判断了。。。
#include <bits/stdc++.h>
#define ll __int64
using  namespace  std;
ll n;

int main(){
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  while(cin>>n){
    if(n<=2){
      cout<<-1<<endl;
      continue;
    }
    else if(n&1){
      n/=2;
      cout<<2*n*n+2*n<<" "<<2*n*n+2*n+1<<endl;
    }
    else{
      n/=2;
      cout<<n*n-1<<" "<<n*n+1<<endl;
    }
  }
  return 0;
}

  另一种想法,我们假设给出的边为一条直角边。另外两条边长分别为a,b,其中b是斜边

           由勾股定理可以得出:a*a+n*n=b*b

           公式稍作调整:(b-a)(b+a)=n*n

           当n为奇数时,只需要使得b-a=1,b+a=n*n即可。

           当n为偶数时,只需要使得b-a=2,b+a=n*n/2即可。

              计算一下极限数据,偶数和奇数分别大概是2.5e17和5e17,不会超过上限。

#include <bits/stdc++.h>
using namespace std;

int main()
{
	long long n,a,b;
	while (~scanf("%I64d",&n)){
		if (n<3){
			printf("-1\n");
			continue;
		}
		if (n%2){
			a=n*n/2;
			b=a+1;
			printf("%I64d %I64d\n",a,b);
		}
		else {
			a=n*n/2/2-1;
			b=a+2;
			printf("%I64d %I64d\n",a,b);
		}
	}
	return 0;
}






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值