AtCoder Beginner Contest 173 A ~ F(已经补完)

时间:2022-07-24
本文章向大家介绍AtCoder Beginner Contest 173 A ~ F(已经补完),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

A 签到:

#include<iostream>
 
using namespace std;
 
int main(){
 int n;
  cin>>n;
  int ans = 1000-n%1000;
  if(ans % 1000 == 0) cout<<0<<endl;
  else cout<<ans<<endl;
  
  return 0;
}

B 签到

#include<iostream>
#include<map>
using namespace std;
 
 
int main(){
	int t;
	cin>>t;
	int num1=0,num2=0,num3=0,num4 =0;
	while(t--){
		string s;
		cin>>s;
	    if(s == "AC") num1++;
	    if(s == "WA") num2++;
	    if(s == "TLE") num3++;
		if(s == "RE") num4++; 
	}
	cout<<"AC x "<<num1<<endl;
	cout<<"WA x "<<num2<<endl;
	cout<<"TLE x "<<num3<<endl;
	cout<<"RE x "<<num4<<endl;
	return 0;
} 

C 思路:二进制枚举 for(int i=0;i<(1<<h);i++) for(int j=0;j<(1<<w);j++) 二进制每次+1就可以暴力遍历每种情况出现的可能性

#include<bits/stdc++.h> 
using namespace std;
#define ll long long
#define endl "n"
int main(){
    ios_base::sync_with_stdio(0);cin.tie(0);
    int n,m,k;
    cin>>n>>m>>k;
    int ans=0;
    bool ar[n][m];
    for(int i=0;i<n;i++)for(int j=0;j<m;j++){
        char x;cin>>x;
        ar[i][j]= x == '#';
    }
    for(int i=0;i<(1<<n);i++){
        for(int j=0;j<(1<<m);j++){
            int cnt=0;
            for(int x=0;x<n;x++){
                for(int y=0;y<m;y++){
                    if(ar[x][y]&&(i&(1<<x))&&(j&(1<<y)))cnt++;
                }
            }
            if(cnt==k)ans++;
        }
    }
    cout<<ans<<endl;
    return 0;
} 

D 既然要让权值最大,那必然要让大的值先插入,否则会被相邻的小的值影响,导致不能贡献权值。所以要先排序。又因为是一个圈,左右两边都能贡献权值,所以除了最大的数只能贡献一次,剩余的数都可以贡献两次。注意判断数量的奇偶。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
long long int  m,t;
long long int a[200005];
int main()
{
	cin >> t;
	for (int i = 1; i <= t; i++)
	{
		cin >> a[i];
	}
	sort(a + 1, a + 1 + t);
	m = a[t];
	int j = t - 1;
	for (int i = (t - 2) / 2; i > 0; i--)
	{
		m += 2 * a[j--];
	}
	if (t % 2 == 1)
	{
		m += a[j];
	}
	cout << m;
}

E 题意:求从n个数选出k个数的乘积最大值结果再取模1e9+7。

思路:对于多个数的乘积想要结果最大,在满足绝对值最大的情况下要满足包含偶数个负数。 对于所选的数是奇数时,首先就取一个最大正数,接下来就是俩个正数积和俩个负数积取最大。 当正数数量为0,且选择数量为奇数时结果一定为负,这时要想结果最大的话就要取k个绝对值最小的数。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
long long int mod = 1e9 + 7;
long long int  n,m;
long long int a[200005];
bool cmp(int x, int y)
{
	return abs(x) < abs(y);
}
int main()
{
	int pn=0 ,nn = 0;
	//pn正数,nn负数;
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
		if (a[i] >= 0)
			pn++;
		else
			nn++;
	}
	int l=1, r=n;//左右逼近
	long long ans = 1;
	if (!pn && m % 2 == 1)//结果必定为负数
	{
		sort(a + 1, a + 1 + n, cmp);
		for (int i = 1; i <= m; i++) 
			ans = a[i] * ans % mod;
	}
	else
	{
		sort(a + 1, a + 1 + n, greater< int >());
		while (m)
		{
			if (m % 2 == 1)//为奇数就乘大的正数
			{
				ans = ans * a[l] % mod;
				l++, m--;
			}
			else
			{
				if (a[l] * a[l + 1] >= a[r] * a[r - 1])
					//两正数乘起来比负数大
				{
					ans = ans * a[l] % mod * a[l + 1] % mod;
					l += 2,m -= 2;
				}
				else
				{
					ans = ans * a[r - 1] % mod * a[r] % mod;
					r -= 2,m -= 2;
				}
			}

		}
	}
	//防止出现负数,故再加mod再取余数
	cout << (ans % mod + mod) % mod << endl;
}

F 题意:给你一棵树,节点为1到n,取若干连续编号的节点,求出其连通分量,问所有连续段的连通分量之和。

思路:直接算不好算所以先算一开始一条边都没有的时候答案是多少,然后每加入一个边,就把含他的s的数量去掉。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
int main()
{
	long long n, l, r,sum=0;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		sum += i * (n - i + 1);
	}
	for (int i = 1; i < n; i++)
	{
		cin >> l >> r;
		if (l > r)
			swap(l, r);
		sum -= l * (n - r + 1);
	}
	cout << sum << endl;
}