Atcoder 173题解(A~E)

A
失误WA了两次耻辱!!!
AC代码:

#include<iostream>
#include<cstdio>
#include <stdio.h>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<map>
#include<vector>
#include <set>
#define ll long long
using namespace std;

int main()
{
    int n;
    cin>>n;
    if(n%1000==0)
    {
        cout<<0<<endl;
    }
    else
    {
        int k=n%1000;
        int c=1000-k;
        cout<<c<<endl;


    }
    return 0;
}

B
简单统计一下
模拟即可
AC代码:

#include<iostream>
#include<cstdio>
#include <stdio.h>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<map>
#include<vector>
#include <set>
#define ll long long
using namespace std;
string a="AC";
string b="WA";
string c="TLE";
string d="RE";
int x[5];
int main()
{
    string k;
    int n;
    cin>>n;
    for(int i=0; i<n; i++)
    {
        cin>>k;
        if(k==a)
        {
            x[1]++;
        }
        else if(k==b)
        {
            x[2]++;
        }
        else if(k==c)
        {
            x[3]++;
        }
        else if(k==d)
        {
            x[4]++;
        }
    }
    cout<<a<<" x "<<x[1]<<endl;
    cout<<b<<" x "<<x[2]<<endl;
    cout<<c<<" x "<<x[3]<<endl;
    cout<<d<<" x "<<x[4]<<endl;
    return 0;
}

C
二进制枚举套娃,套两层即可
AC代码:

#include<iostream>
#include<cstdio>
#include <stdio.h>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<map>
#include<vector>
#include <set>
#define ll long long
using namespace std;
char maps[7][7];
int sum;
int ans;
int a[7];//纪录每行的总和
int b[7];//纪录每列的总和

int main()
{
    int n,m,k;
    cin>>n>>m>>k;
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
        {
            cin>>maps[i][j];
            if(maps[i][j]=='#')
            {
                sum++;
                a[i]++;
                b[j]++;
            }
        }
    }
    //if(sum==k)
    //{
       // ans++;
  //  }
    for(int i = 0; i < (1<<n); i++)//行枚举
    {
        for(int x = 0; x < (1<<m); x++)//列枚举
        {
            int t=sum;
            for(int j = 0; j < n; j++)//减去行的
            {

                if(i & (1 << j))
                {
                    t=t-a[j];
                }
            }
            for(int y = 0; y < m; y++)//减去列的
            {
                if(x & (1 << y))
                {
                    t=t-b[y];
                }
            }
            for(int j = 0; j < n; j++)
            {
                for(int y = 0; y < m; y++)
                {
                    if(i & (1 << j)&&x & (1 << y))//加上反复减去的
                    {
                        if(maps[j][y]=='#')
                        {
                            t++;
                        }
                    }
                }
            }
            if(t==k)
            {
                //cout<<i<<y<<endl;
                ans++;
            }

        }
    }
    cout<<ans<<endl;
    return 0;
}

D
从大到小最大的数只能贡献一次友好值,其余均可以共享两次,贪心即可。
AC代码:

#include<iostream>
#include<cstdio>
#include <stdio.h>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<map>
#include<vector>
#include <set>
#define ll long long
using namespace std;
int a[200010];
ll sum;
int main()
{
    int n;
    cin>>n;
    for(int i=0; i<n; i++)
    {
        cin>>a[i];
    }
    sort(a,a+n);
    if(n>1)
    {
        sum+=a[n-1];
    }
    int k=n-2;
    n=n-2;
    while(n>=2)
    {
        sum=sum+2*a[k--];
        n=n-2;

    }
    if(n==1)
    {
        sum+=a[k];
    }
    cout<<sum<<endl;
    return 0;
}

E
N个数取K个数的积最大,分为四种情况
第一种:全是正数,则取最大的K个数的积
第二种:没有正数,则取最大的K个数的积
第三种:有正有负,按照绝对值排列,对最大的K个的值进行判断,如果值为正,则直接输出,如果为负则判断前N-K个数中最大的正数于后K个数中的最小负数交换,将前N-K个数中最大的负数于后K个数中最小的正数交换,比较大小即可
AC代码:

#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>

using namespace std;

long long  n, k;
long long ans = 1;
long long  l_neg = -1,l_pos = -1, r_neg = -1, r_pos = -1;
//l_neg表示前N-K项最大的负数,l_pos表示前N-K项最大的正数,r_neg表示后K项最小负数,r-pos表示后K项最小正数
const long long int M = 1000000007;

bool cmp(long long int a,long long  int b)//按照绝对值排序
{
    return abs(a) < abs(b);
}

long long int calc(vector<long long int> a)
{
    long long temp = 1;
    for(long long int i = n - k; i < n; i++)
        temp = (temp * a[i]) % M;
    return (temp+M)%M;
}
int main()
{
    cin >> n >> k;
    vector<long long int> a(n, 0);
    for(long long int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    sort(a.begin(), a.end(), cmp);
    for(long long int i = n - k; i < n; i++)
    {
        ans = (ans * a[i]) % M;//计算后K项的积
        if(r_pos == -1 && a[i] > 0)//找出后K项中最小的正数
            r_pos = i;
        if(r_neg == -1 && a[i] < 0)//找出后K项中最小的负数
            r_neg = i;
    }
    for(long long int i = n - k - 1; i >= 0; i--)
    {
        if(l_pos == -1 && a[i] > 0)//找出前N-K项中最大的正数
            l_pos = i;
        if(l_neg == -1 && a[i] < 0)//找出前N-K项中最大的负数
            l_neg = i;
    }

    if(ans < 0 && n != k)
    {
        if(r_pos == -1)//如果后K项没有正数
        {
            if(l_pos == -1)//如果前N-K项也没有正数
            {
                ans = 1;
                for(long long int i = 0; i < k; i++)
                    ans = (ans * a[i]) % M;
            }
            else
            {
                swap(a[l_pos], a[r_neg]);
                ans = calc(a);
            }
        }
        else
        {
            if(l_neg == -1)
            {
                swap(a[l_pos], a[r_neg]);
                ans = calc(a);
            }
            else if(l_pos == -1)
            {
                swap(a[l_neg], a[r_pos]);
                ans = calc(a);
            }
            else
            {
                vector<long long int> c1 = a;
                vector<long long int> c2 = a;
                swap(c1[l_neg], c1[r_pos]);
                swap(c2[l_pos], c2[r_neg]);
                ans=(abs(a[l_neg]*a[r_neg])>abs(a[l_pos]*a[r_pos]))?calc(c1):calc(c2);//判断交换之后哪一个比较大
            }
        }
    }
    cout << (ans+M)%M << endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AtCoder Beginner Contest 134 是一场 AtCoder 的入门级比赛,以下是每道题的简要题解: A - Dodecagon 题目描述:已知一个正十二边形的边长,求它的面积。 解题思路:正十二边形的内角为 $150^\circ$,因此可以将正十二边形拆分为 12 个等腰三角形,通过三角形面积公式计算面积即可。 B - Golden Apple 题目描述:有 $N$ 个苹果和 $D$ 个盘子,每个盘子最多可以装下 $2D+1$ 个苹果,求最少需要多少个盘子才能装下所有的苹果。 解题思路:每个盘子最多可以装下 $2D+1$ 个苹果,因此可以将苹果平均分配到每个盘子中,可以得到最少需要 $\lceil \frac{N}{2D+1} \rceil$ 个盘子。 C - Exception Handling 题目描述:给定一个长度为 $N$ 的整数序列 $a$,求除了第 $i$ 个数以外的最大值。 解题思路:可以使用两个变量 $m_1$ 和 $m_2$ 分别记录最大值和次大值。遍历整个序列,当当前数不是第 $i$ 个数时,更新最大值和次大值。因此,最后的结果应该是 $m_1$ 或 $m_2$ 中较小的一个。 D - Preparing Boxes 题目描述:有 $N$ 个盒子和 $M$ 个物品,第 $i$ 个盒子可以放入 $a_i$ 个物品,每个物品只能放在一个盒子中。现在需要将所有的物品放入盒子中,每次操作可以将一个盒子内的物品全部取出并分配到其他盒子中,求最少需要多少次操作才能完成任务。 解题思路:首先可以计算出所有盒子中物品的总数 $S$,然后判断是否存在一个盒子的物品数量大于 $\lceil \frac{S}{2} \rceil$,如果存在,则无法完成任务。否则,可以用贪心的思想,每次从物品数量最多的盒子中取出一个物品,放入物品数量最少的盒子中。因为每次操作都会使得物品数量最多的盒子的物品数量减少,而物品数量最少的盒子的物品数量不变或增加,因此这种贪心策略可以保证最少需要的操作次数最小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值